1
/* PROJECT: ReactOS CE Applications Manager
2 * LICENSE: GPL - See COPYING in the top level directory
3 * AUTHORS: David Quintana <gigaherz@gmail.com>
4 * Alexander Shaposhnikov <chaez.san@gmail.com>
9 #include <shlobj_undoc.h>
10 #include <shlguid_undoc.h>
16 #include <shellutils.h>
21 #include "crichedit.h"
23 #define SEARCH_TIMER_ID 'SR'
25 HWND hListView
= NULL
;
28 public CUiWindow
< CToolbar
<> >
30 #define TOOLBAR_HEIGHT 24
32 WCHAR szInstallBtn
[MAX_STR_LEN
];
33 WCHAR szUninstallBtn
[MAX_STR_LEN
];
34 WCHAR szModifyBtn
[MAX_STR_LEN
];
36 VOID
AddImageToImageList(HIMAGELIST hImageList
, UINT ImageIndex
)
40 if (!(hImage
= (HICON
) LoadImage(hInst
,
41 MAKEINTRESOURCE(ImageIndex
),
47 /* TODO: Error message */
50 ImageList_AddIcon(hImageList
, hImage
);
54 HIMAGELIST
InitImageList(VOID
)
56 HIMAGELIST hImageList
;
58 /* Create the toolbar icon image list */
59 hImageList
= ImageList_Create(TOOLBAR_HEIGHT
,//GetSystemMetrics(SM_CXSMICON),
60 TOOLBAR_HEIGHT
,//GetSystemMetrics(SM_CYSMICON),
61 ILC_MASK
| GetSystemColorDepth(),
66 /* TODO: Error message */
70 AddImageToImageList(hImageList
, IDI_INSTALL
);
71 AddImageToImageList(hImageList
, IDI_UNINSTALL
);
72 AddImageToImageList(hImageList
, IDI_MODIFY
);
73 AddImageToImageList(hImageList
, IDI_REFRESH
);
74 AddImageToImageList(hImageList
, IDI_UPDATE_DB
);
75 AddImageToImageList(hImageList
, IDI_SETTINGS
);
76 AddImageToImageList(hImageList
, IDI_EXIT
);
82 VOID
OnGetDispInfo(LPTOOLTIPTEXT lpttt
)
84 UINT idButton
= (UINT
) lpttt
->hdr
.idFrom
;
89 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EXIT
);
93 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_INSTALL
);
97 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_UNINSTALL
);
101 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_MODIFY
);
105 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_SETTINGS
);
109 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH
);
113 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_UPDATE_DB
);
118 HWND
Create(HWND hwndParent
)
120 HIMAGELIST hImageList
;
123 static TBBUTTON Buttons
[] =
124 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
125 { 0, ID_INSTALL
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szInstallBtn
},
126 { 1, ID_UNINSTALL
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szUninstallBtn
},
127 { 2, ID_MODIFY
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szModifyBtn
},
128 { 5, 0, TBSTATE_ENABLED
, BTNS_SEP
, { 0 }, 0, 0 },
129 { 3, ID_REFRESH
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
130 { 4, ID_RESETDB
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, {0}, 0, 0},
131 { 5, 0, TBSTATE_ENABLED
, BTNS_SEP
, { 0 }, 0, 0 },
132 { 5, ID_SETTINGS
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
133 { 6, ID_EXIT
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 }
136 LoadStringW(hInst
, IDS_INSTALL
, szInstallBtn
, _countof(szInstallBtn
));
137 LoadStringW(hInst
, IDS_UNINSTALL
, szUninstallBtn
, _countof(szUninstallBtn
));
138 LoadStringW(hInst
, IDS_MODIFY
, szModifyBtn
, _countof(szModifyBtn
));
140 m_hWnd
= CreateWindowExW(0, TOOLBARCLASSNAMEW
, NULL
,
141 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
| TBSTYLE_LIST
,
148 /* TODO: Show error message */
152 SendMessageW(TB_SETEXTENDEDSTYLE
, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
153 SetButtonStructSize();
155 hImageList
= InitImageList();
159 /* TODO: Show error message */
163 ImageList_Destroy((HIMAGELIST
) SetImageList(hImageList
));
165 AddButtons(_countof(Buttons
), Buttons
);
171 class CAppsListView
:
172 public CUiWindow
<CListView
>
188 VOID
ColumnClick(LPNMLISTVIEW pnmv
)
190 SortContext ctx
= {this, pnmv
->iSubItem
};
192 SortItems(s_CompareFunc
, &ctx
);
194 bAscending
= !bAscending
;
197 PVOID
GetLParam(INT Index
)
204 ItemIndex
= (INT
) SendMessage(LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
213 ZeroMemory(&Item
, sizeof(Item
));
215 Item
.mask
= LVIF_PARAM
;
216 Item
.iItem
= ItemIndex
;
220 return (PVOID
) Item
.lParam
;
223 BOOL
AddColumn(INT Index
, ATL::CStringW
& Text
, INT Width
, INT Format
)
225 BOOL result
= AddColumn(Index
, Text
.GetBuffer(), Width
, Format
);
230 BOOL
AddColumn(INT Index
, LPWSTR lpText
, INT Width
, INT Format
)
234 ZeroMemory(&Column
, sizeof(Column
));
236 Column
.mask
= LVCF_FMT
| LVCF_TEXT
| LVCF_WIDTH
| LVCF_SUBITEM
;
237 Column
.iSubItem
= Index
;
238 Column
.pszText
= (LPTSTR
) lpText
;
242 return (InsertColumn(Index
, &Column
) == -1) ? FALSE
: TRUE
;
245 INT
AddItem(INT ItemIndex
, INT IconIndex
, LPWSTR lpText
, LPARAM lParam
)
249 ZeroMemory(&Item
, sizeof(Item
));
251 Item
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
252 Item
.pszText
= lpText
;
253 Item
.lParam
= lParam
;
254 Item
.iItem
= ItemIndex
;
255 Item
.iImage
= IconIndex
;
257 return InsertItem(&Item
);
260 static INT CALLBACK
s_CompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
262 SortContext
* ctx
= ((SortContext
*) lParamSort
);
263 return ctx
->lvw
->CompareFunc(lParam1
, lParam2
, ctx
->iSubItem
);
266 INT
CompareFunc(LPARAM lParam1
, LPARAM lParam2
, INT iSubItem
)
268 ATL::CStringW Item1
, Item2
;
269 LVFINDINFO IndexInfo
;
272 IndexInfo
.flags
= LVFI_PARAM
;
274 IndexInfo
.lParam
= lParam1
;
275 Index
= FindItem(-1, &IndexInfo
);
276 GetItemText(Index
, iSubItem
, Item1
.GetBuffer(MAX_STR_LEN
), MAX_STR_LEN
);
277 Item1
.ReleaseBuffer();
279 IndexInfo
.lParam
= lParam2
;
280 Index
= FindItem(-1, &IndexInfo
);
281 GetItemText(Index
, iSubItem
, Item2
.GetBuffer(MAX_STR_LEN
), MAX_STR_LEN
);
282 Item2
.ReleaseBuffer();
285 return Item2
== Item1
;
287 return Item1
== Item2
;
292 HWND
Create(HWND hwndParent
)
294 RECT r
= {205, 28, 465, 250};
295 DWORD style
= WS_CHILD
| WS_VISIBLE
| LVS_SORTASCENDING
| LVS_REPORT
| LVS_SINGLESEL
| LVS_SHOWSELALWAYS
;
296 HMENU menu
= GetSubMenu(LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_APPLICATIONMENU
)), 0);
298 HWND hwnd
= CListView::Create(hwndParent
, r
, NULL
, style
, WS_EX_CLIENTEDGE
, menu
);
301 SetExtendedListViewStyle(LVS_EX_FULLROWSELECT
);
308 class CSideTreeView
:
309 public CUiWindow
<CTreeView
>
311 HIMAGELIST hImageTreeView
= ImageList_Create(TREEVIEW_ICON_SIZE
, TREEVIEW_ICON_SIZE
,
312 GetSystemColorDepth() | ILC_MASK
,
316 HTREEITEM
AddItem(HTREEITEM hParent
, ATL::CStringW
&Text
, INT Image
, INT SelectedImage
, LPARAM lParam
)
318 HTREEITEM result
= CUiWindow
<CTreeView
>::AddItem(hParent
, Text
.GetBuffer(), Image
, SelectedImage
, lParam
);
319 Text
.ReleaseBuffer();
323 HTREEITEM
AddCategory(HTREEITEM hRootItem
, UINT TextIndex
, UINT IconIndex
)
325 ATL::CStringW szText
;
329 hIcon
= (HICON
) LoadImage(hInst
,
330 MAKEINTRESOURCE(IconIndex
),
334 LR_CREATEDIBSECTION
);
337 Index
= ImageList_AddIcon(hImageTreeView
, hIcon
);
341 szText
.LoadStringW(hInst
, TextIndex
);
342 return AddItem(hRootItem
, szText
, Index
, Index
, TextIndex
);
345 HIMAGELIST
SetImageList()
347 return CUiWindow
<CTreeView
>::SetImageList(hImageTreeView
, TVSIL_NORMAL
);
350 VOID
DestroyImageList()
353 ImageList_Destroy(hImageTreeView
);
359 CUiWindow
<CTreeView
>::~CUiWindow();
367 VOID
SetText(LPCWSTR lpszText
)
369 SendMessage(SB_SETTEXT
, SBT_NOBORDERS
, (LPARAM
) lpszText
);
372 HWND
Create(HWND hwndParent
)
375 m_hWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, L
"Edit", NULL
,
376 WS_CHILD
| WS_VISIBLE
| ES_LEFT
| ES_AUTOHSCROLL
,
378 hwndParent
, (HMENU
) NULL
,
381 SendMessageW(WM_SETFONT
, (WPARAM
) GetStockObject(DEFAULT_GUI_FONT
), 0);
382 szBuf
.LoadStringW(hInst
, IDS_SEARCH_TEXT
);
383 SetWindowTextW(szBuf
);
390 public CWindowImpl
<CMainWindow
, CWindow
, CFrameWinTraits
>
392 CUiPanel
* m_ClientPanel
;
393 CUiSplitPanel
* m_VSplitter
;
394 CUiSplitPanel
* m_HSplitter
;
396 CMainToolbar
* m_Toolbar
;
397 CAppsListView
* m_ListView
;
399 CSideTreeView
* m_TreeView
;
400 CUiWindow
<CStatusBar
> * m_StatusBar
;
401 CUiWindow
<CRichEdit
> * m_RichEdit
;
403 CUiWindow
<CSearchBar
> * m_SearchBar
;
419 VOID
InitApplicationsList(VOID
)
421 ATL::CStringW szText
;
423 /* Add columns to ListView */
424 szText
.LoadStringW(hInst
, IDS_APP_NAME
);
425 m_ListView
->AddColumn(0, szText
, 200, LVCFMT_LEFT
);
427 szText
.LoadStringW(hInst
, IDS_APP_INST_VERSION
);
428 m_ListView
->AddColumn(1, szText
, 90, LVCFMT_RIGHT
);
430 szText
.LoadStringW(hInst
, IDS_APP_DESCRIPTION
);
431 m_ListView
->AddColumn(3, szText
, 250, LVCFMT_LEFT
);
433 UpdateApplicationsList(ENUM_ALL_COMPONENTS
);
436 HTREEITEM
AddCategory(HTREEITEM hRootItem
, UINT TextIndex
, UINT IconIndex
)
438 return m_TreeView
->AddCategory(hRootItem
, TextIndex
, IconIndex
);
441 VOID
InitCategoriesList(VOID
)
445 hRootItem
= AddCategory(TVI_ROOT
, IDS_AVAILABLEFORINST
, IDI_CATEGORY
);
446 AddCategory(hRootItem
, IDS_CAT_AUDIO
, IDI_CAT_AUDIO
);
447 AddCategory(hRootItem
, IDS_CAT_VIDEO
, IDI_CAT_VIDEO
);
448 AddCategory(hRootItem
, IDS_CAT_GRAPHICS
, IDI_CAT_GRAPHICS
);
449 AddCategory(hRootItem
, IDS_CAT_GAMES
, IDI_CAT_GAMES
);
450 AddCategory(hRootItem
, IDS_CAT_INTERNET
, IDI_CAT_INTERNET
);
451 AddCategory(hRootItem
, IDS_CAT_OFFICE
, IDI_CAT_OFFICE
);
452 AddCategory(hRootItem
, IDS_CAT_DEVEL
, IDI_CAT_DEVEL
);
453 AddCategory(hRootItem
, IDS_CAT_EDU
, IDI_CAT_EDU
);
454 AddCategory(hRootItem
, IDS_CAT_ENGINEER
, IDI_CAT_ENGINEER
);
455 AddCategory(hRootItem
, IDS_CAT_FINANCE
, IDI_CAT_FINANCE
);
456 AddCategory(hRootItem
, IDS_CAT_SCIENCE
, IDI_CAT_SCIENCE
);
457 AddCategory(hRootItem
, IDS_CAT_TOOLS
, IDI_CAT_TOOLS
);
458 AddCategory(hRootItem
, IDS_CAT_DRIVERS
, IDI_CAT_DRIVERS
);
459 AddCategory(hRootItem
, IDS_CAT_LIBS
, IDI_CAT_LIBS
);
460 AddCategory(hRootItem
, IDS_CAT_OTHER
, IDI_CAT_OTHER
);
462 m_TreeView
->SetImageList();
463 m_TreeView
->Expand(hRootItem
, TVE_EXPAND
);
464 m_TreeView
->SelectItem(hRootItem
);
467 BOOL
CreateStatusBar()
469 m_StatusBar
= new CUiWindow
<CStatusBar
>();
470 m_StatusBar
->m_VerticalAlignment
= UiAlign_RightBtm
;
471 m_StatusBar
->m_HorizontalAlignment
= UiAlign_Stretch
;
472 m_ClientPanel
->Children().Append(m_StatusBar
);
474 return m_StatusBar
->Create(m_hWnd
, (HMENU
) IDC_STATUSBAR
) != NULL
;
479 m_Toolbar
= new CMainToolbar();
480 m_Toolbar
->m_VerticalAlignment
= UiAlign_LeftTop
;
481 m_Toolbar
->m_HorizontalAlignment
= UiAlign_Stretch
;
482 m_ClientPanel
->Children().Append(m_Toolbar
);
484 return m_Toolbar
->Create(m_hWnd
) != NULL
;
487 BOOL
CreateTreeView()
489 m_TreeView
= new CSideTreeView();
490 m_TreeView
->m_VerticalAlignment
= UiAlign_Stretch
;
491 m_TreeView
->m_HorizontalAlignment
= UiAlign_Stretch
;
492 m_VSplitter
->First().Append(m_TreeView
);
494 return m_TreeView
->Create(m_hWnd
) != NULL
;
497 BOOL
CreateListView()
499 m_ListView
= new CAppsListView();
500 m_ListView
->m_VerticalAlignment
= UiAlign_Stretch
;
501 m_ListView
->m_HorizontalAlignment
= UiAlign_Stretch
;
502 m_HSplitter
->First().Append(m_ListView
);
504 hListView
= m_ListView
->Create(m_hWnd
);
505 return hListView
!= NULL
;
508 BOOL
CreateRichEdit()
510 m_RichEdit
= new CUiWindow
<CRichEdit
>();
511 m_RichEdit
->m_VerticalAlignment
= UiAlign_Stretch
;
512 m_RichEdit
->m_HorizontalAlignment
= UiAlign_Stretch
;
513 m_HSplitter
->Second().Append(m_RichEdit
);
515 return m_RichEdit
->Create(m_hWnd
) != NULL
;
518 BOOL
CreateVSplitter()
520 m_VSplitter
= new CUiSplitPanel();
521 m_VSplitter
->m_VerticalAlignment
= UiAlign_Stretch
;
522 m_VSplitter
->m_HorizontalAlignment
= UiAlign_Stretch
;
523 m_VSplitter
->m_DynamicFirst
= FALSE
;
524 m_VSplitter
->m_Horizontal
= FALSE
;
525 m_VSplitter
->m_MinFirst
= 240;
526 m_VSplitter
->m_MinSecond
= 300;
527 m_ClientPanel
->Children().Append(m_VSplitter
);
529 return m_VSplitter
->Create(m_hWnd
) != NULL
;
532 BOOL
CreateHSplitter()
534 m_HSplitter
= new CUiSplitPanel();
535 m_HSplitter
->m_VerticalAlignment
= UiAlign_Stretch
;
536 m_HSplitter
->m_HorizontalAlignment
= UiAlign_Stretch
;
537 m_HSplitter
->m_DynamicFirst
= TRUE
;
538 m_HSplitter
->m_Horizontal
= TRUE
;
539 m_HSplitter
->m_Pos
= 32768;
540 m_HSplitter
->m_MinFirst
= 300;
541 m_HSplitter
->m_MinSecond
= 80;
542 m_VSplitter
->Second().Append(m_HSplitter
);
544 return m_HSplitter
->Create(m_hWnd
) != NULL
;
547 BOOL
CreateSearchBar(VOID
)
549 m_SearchBar
= new CUiWindow
<CSearchBar
>();
550 m_SearchBar
->m_VerticalAlignment
= UiAlign_LeftTop
;
551 m_SearchBar
->m_HorizontalAlignment
= UiAlign_RightBtm
;
552 m_SearchBar
->m_Margin
.top
= 6;
553 m_SearchBar
->m_Margin
.right
= 6;
555 return m_SearchBar
->Create(m_Toolbar
->m_hWnd
) != NULL
;
562 m_ClientPanel
= new CUiPanel();
563 m_ClientPanel
->m_VerticalAlignment
= UiAlign_Stretch
;
564 m_ClientPanel
->m_HorizontalAlignment
= UiAlign_Stretch
;
567 b
= b
&& CreateStatusBar();
568 b
= b
&& CreateToolbar();
569 b
= b
&& CreateSearchBar();
570 b
= b
&& CreateVSplitter();
573 b
= b
&& CreateHSplitter();
574 b
= b
&& CreateTreeView();
577 b
= b
&& CreateListView();
578 b
= b
&& CreateRichEdit();
585 /* Size status bar */
586 m_StatusBar
->SendMessage(WM_SIZE
, 0, 0);
589 m_Toolbar
->AutoSize();
591 ::GetWindowRect(m_Toolbar
->m_hWnd
, &rTop
);
592 ::GetWindowRect(m_StatusBar
->m_hWnd
, &rBottom
);
594 m_VSplitter
->m_Margin
.top
= rTop
.bottom
- rTop
.top
;
595 m_VSplitter
->m_Margin
.bottom
= rBottom
.bottom
- rBottom
.top
;
605 ATL::CStringW szBuffer1
, szBuffer2
;
607 InitApplicationsList();
609 InitCategoriesList();
611 szBuffer2
.LoadStringW(hInst
, IDS_APPS_COUNT
);
612 szBuffer1
.Format(szBuffer2
, m_ListView
->GetItemCount());
614 m_StatusBar
->SetText(szBuffer1
);
621 VOID
OnSize(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
623 /* Size status bar */
624 m_StatusBar
->SendMessage(WM_SIZE
, 0, 0);
627 m_Toolbar
->AutoSize();
630 RECT r
= {0, 0, LOWORD(lParam
), HIWORD(lParam
)};
634 int count
= m_ClientPanel
->CountSizableChildren();
635 hdwp
= BeginDeferWindowPos(count
);
636 if (hdwp
) hdwp
= m_ClientPanel
->OnParentSize(r
, hdwp
);
637 if (hdwp
) EndDeferWindowPos(hdwp
);
639 // TODO: Sub-layouts for children of children
640 count
= m_SearchBar
->CountSizableChildren();
641 hdwp
= BeginDeferWindowPos(count
);
642 if (hdwp
) hdwp
= m_SearchBar
->OnParentSize(r
, hdwp
);
643 if (hdwp
) EndDeferWindowPos(hdwp
);
646 BOOL
ProcessWindowMessage(HWND hwnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, LRESULT
& theResult
, DWORD dwMapId
)
653 ::PostMessage(hwnd
, WM_CLOSE
, 0, 0);
663 FreeCachedAvailableEntries();
665 if (IS_INSTALLED_ENUM(SelectedEnumType
))
666 FreeInstalledAppList();
668 delete m_ClientPanel
;
675 OnCommand(wParam
, lParam
);
680 LPNMHDR data
= (LPNMHDR
) lParam
;
686 if (data
->hwndFrom
== m_TreeView
->m_hWnd
)
688 switch (((LPNMTREEVIEW
) lParam
)->itemNew
.lParam
)
691 UpdateApplicationsList(ENUM_ALL_COMPONENTS
);
694 case IDS_APPLICATIONS
:
695 UpdateApplicationsList(ENUM_APPLICATIONS
);
699 UpdateApplicationsList(ENUM_UPDATES
);
702 case IDS_AVAILABLEFORINST
:
703 UpdateApplicationsList(ENUM_ALL_AVAILABLE
);
707 UpdateApplicationsList(ENUM_CAT_AUDIO
);
711 UpdateApplicationsList(ENUM_CAT_DEVEL
);
714 case IDS_CAT_DRIVERS
:
715 UpdateApplicationsList(ENUM_CAT_DRIVERS
);
719 UpdateApplicationsList(ENUM_CAT_EDU
);
722 case IDS_CAT_ENGINEER
:
723 UpdateApplicationsList(ENUM_CAT_ENGINEER
);
726 case IDS_CAT_FINANCE
:
727 UpdateApplicationsList(ENUM_CAT_FINANCE
);
731 UpdateApplicationsList(ENUM_CAT_GAMES
);
734 case IDS_CAT_GRAPHICS
:
735 UpdateApplicationsList(ENUM_CAT_GRAPHICS
);
738 case IDS_CAT_INTERNET
:
739 UpdateApplicationsList(ENUM_CAT_INTERNET
);
743 UpdateApplicationsList(ENUM_CAT_LIBS
);
747 UpdateApplicationsList(ENUM_CAT_OFFICE
);
751 UpdateApplicationsList(ENUM_CAT_OTHER
);
754 case IDS_CAT_SCIENCE
:
755 UpdateApplicationsList(ENUM_CAT_SCIENCE
);
759 UpdateApplicationsList(ENUM_CAT_TOOLS
);
763 UpdateApplicationsList(ENUM_CAT_VIDEO
);
768 HMENU mainMenu
= ::GetMenu(hwnd
);
769 HMENU lvwMenu
= ::GetMenu(m_ListView
->m_hWnd
);
771 /* Disable/enable items based on treeview selection */
772 if (IsSelectedNodeInstalled())
774 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_ENABLED
);
775 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_GRAYED
);
776 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_ENABLED
);
777 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_ENABLED
);
779 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_ENABLED
);
780 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_GRAYED
);
781 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_ENABLED
);
782 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_ENABLED
);
784 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_REGREMOVE
, TRUE
);
785 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_INSTALL
, FALSE
);
786 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_UNINSTALL
, TRUE
);
787 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_MODIFY
, TRUE
);
791 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_GRAYED
);
792 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_ENABLED
);
793 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_GRAYED
);
794 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_GRAYED
);
796 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_GRAYED
);
797 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_ENABLED
);
798 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_GRAYED
);
799 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_GRAYED
);
801 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_REGREMOVE
, FALSE
);
802 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_INSTALL
, TRUE
);
803 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_UNINSTALL
, FALSE
);
804 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_MODIFY
, FALSE
);
809 case LVN_ITEMCHANGED
:
811 LPNMLISTVIEW pnic
= (LPNMLISTVIEW
) lParam
;
813 if (pnic
->hdr
.hwndFrom
== m_ListView
->m_hWnd
)
815 /* Check if this is a valid item
816 * (technically, it can be also an unselect) */
817 INT ItemIndex
= pnic
->iItem
;
818 if (ItemIndex
== -1 ||
819 ItemIndex
>= ListView_GetItemCount(pnic
->hdr
.hwndFrom
))
824 /* Check if the focus has been moved to another item */
825 if ((pnic
->uChanged
& LVIF_STATE
) &&
826 (pnic
->uNewState
& LVIS_FOCUSED
) &&
827 !(pnic
->uOldState
& LVIS_FOCUSED
))
829 if (IS_INSTALLED_ENUM(SelectedEnumType
))
830 ShowInstalledAppInfo(ItemIndex
);
831 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
832 ShowAvailableAppInfo(ItemIndex
);
838 case LVN_COLUMNCLICK
:
840 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
) lParam
;
842 m_ListView
->ColumnClick(pnmv
);
848 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
850 if (IS_INSTALLED_ENUM(SelectedEnumType
))
851 ShowInstalledAppInfo(-1);
852 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
853 ShowAvailableAppInfo(-1);
860 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
862 /* this won't do anything if the program is already installed */
863 SendMessage(hwnd
, WM_COMMAND
, ID_INSTALL
, 0);
870 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
872 ShowPopupMenu(m_ListView
->m_hWnd
, 0, ID_INSTALL
);
878 OnLink((ENLINK
*) lParam
);
881 case TTN_GETDISPINFO
:
882 m_Toolbar
->OnGetDispInfo((LPTOOLTIPTEXT
) lParam
);
889 OnSize(hwnd
, wParam
, lParam
);
894 LPRECT pRect
= (LPRECT
) lParam
;
896 if (pRect
->right
- pRect
->left
< 565)
897 pRect
->right
= pRect
->left
+ 565;
899 if (pRect
->bottom
- pRect
->top
< 300)
900 pRect
->bottom
= pRect
->top
+ 300;
905 case WM_SYSCOLORCHANGE
:
907 /* Forward WM_SYSCOLORCHANGE to common controls */
908 m_ListView
->SendMessage(WM_SYSCOLORCHANGE
, 0, 0);
909 m_TreeView
->SendMessage(WM_SYSCOLORCHANGE
, 0, 0);
910 m_Toolbar
->SendMessage(WM_SYSCOLORCHANGE
, 0, 0);
911 m_ListView
->SendMessage(EM_SETBKGNDCOLOR
, 0, GetSysColor(COLOR_BTNFACE
));
916 if (wParam
== SEARCH_TIMER_ID
)
918 ::KillTimer(hwnd
, SEARCH_TIMER_ID
);
919 UpdateApplicationsList(-1);
927 virtual VOID
OnLink(ENLINK
*Link
)
934 if (pLink
) HeapFree(GetProcessHeap(), 0, pLink
);
936 pLink
= (LPWSTR
) HeapAlloc(GetProcessHeap(), 0,
937 (max(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) -
938 min(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) + 1) * sizeof(WCHAR
));
941 /* TODO: Error message */
945 m_RichEdit
->SendMessageW(EM_SETSEL
, Link
->chrg
.cpMin
, Link
->chrg
.cpMax
);
946 m_RichEdit
->SendMessageW(EM_GETSELTEXT
, 0, (LPARAM
) pLink
);
948 ShowPopupMenu(m_RichEdit
->m_hWnd
, IDR_LINKMENU
, -1);
954 BOOL
IsSelectedNodeInstalled(void)
956 HTREEITEM hSelectedItem
= m_TreeView
->GetSelection();
959 tItem
.mask
= TVIF_PARAM
| TVIF_HANDLE
;
960 tItem
.hItem
= hSelectedItem
;
961 m_TreeView
->GetItem(&tItem
);
962 switch (tItem
.lParam
)
965 case IDS_APPLICATIONS
:
973 VOID
OnCommand(WPARAM wParam
, LPARAM lParam
)
975 WORD wCommand
= LOWORD(wParam
);
977 if (lParam
== (LPARAM
) m_SearchBar
->m_hWnd
)
981 switch (HIWORD(wParam
))
985 ATL::CStringW szWndText
;
987 szBuf
.LoadStringW(hInst
, IDS_SEARCH_TEXT
);
988 m_SearchBar
->GetWindowTextW(szWndText
);
989 if (szBuf
== szWndText
)
991 SearchEnabled
= FALSE
;
992 m_SearchBar
->SetWindowTextW(L
"");
999 m_SearchBar
->GetWindowTextW(szBuf
);
1000 if (szBuf
.IsEmpty())
1002 szBuf
.LoadStringW(hInst
, IDS_SEARCH_TEXT
);
1003 SearchEnabled
= FALSE
;
1004 m_SearchBar
->SetWindowTextW(szBuf
.GetString());
1011 ATL::CStringW szWndText
;
1015 SearchEnabled
= TRUE
;
1019 szBuf
.LoadStringW(hInst
, IDS_SEARCH_TEXT
);
1020 m_SearchBar
->GetWindowTextW(szWndText
);
1021 if (szBuf
== szWndText
)
1023 szSearchPattern
.Empty();
1027 szSearchPattern
= szWndText
;
1031 SystemParametersInfo(SPI_GETMENUSHOWDELAY
, 0, &dwDelay
, 0);
1032 SetTimer(SEARCH_TIMER_ID
, dwDelay
);
1043 ShellExecuteW(m_hWnd
, L
"open", pLink
, NULL
, NULL
, SW_SHOWNOACTIVATE
);
1044 HeapFree(GetProcessHeap(), 0, pLink
);
1048 CopyTextToClipboard(pLink
);
1049 HeapFree(GetProcessHeap(), 0, pLink
);
1053 CreateSettingsDlg(m_hWnd
);
1057 PostMessageW(WM_CLOSE
, 0, 0);
1061 if (DownloadApplication(-1))
1062 /* TODO: Implement install dialog
1063 * if (InstallApplication(-1))
1065 UpdateApplicationsList(-1);
1069 if (UninstallApplication(-1, FALSE
))
1070 UpdateApplicationsList(-1);
1074 if (UninstallApplication(-1, TRUE
))
1075 UpdateApplicationsList(-1);
1079 RemoveAppFromRegistry(-1);
1083 UpdateApplicationsList(-1);
1088 UpdateApplicationsList(-1);
1092 MessageBoxW(L
"Help not implemented yet", NULL
, MB_OK
);
1101 VOID
FreeInstalledAppList(VOID
)
1103 INT Count
= ListView_GetItemCount(hListView
) - 1;
1104 PINSTALLED_INFO Info
;
1108 Info
= (PINSTALLED_INFO
) ListViewGetlParam(Count
);
1111 RegCloseKey(Info
->hSubKey
);
1118 static BOOL
SearchPatternMatch(PCWSTR szHaystack
, PCWSTR szNeedle
)
1122 /* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
1123 return StrStrIW(szHaystack
, szNeedle
) != NULL
;
1126 static BOOL CALLBACK
s_EnumInstalledAppProc(INT ItemIndex
, LPWSTR lpName
, PINSTALLED_INFO Info
)
1128 PINSTALLED_INFO ItemInfo
;
1129 ATL::CStringW szText
;
1132 if (!SearchPatternMatch(lpName
, szSearchPattern
))
1134 RegCloseKey(Info
->hSubKey
);
1138 ItemInfo
= (PINSTALLED_INFO
) HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO
));
1141 RegCloseKey(Info
->hSubKey
);
1145 RtlCopyMemory(ItemInfo
, Info
, sizeof(INSTALLED_INFO
));
1147 Index
= ListViewAddItem(ItemIndex
, 0, lpName
, (LPARAM
) ItemInfo
);
1149 /* Get version info */
1150 GetApplicationString(ItemInfo
->hSubKey
, L
"DisplayVersion", szText
);
1151 ListView_SetItemText(hListView
, Index
, 1, szText
.GetBuffer());
1152 szText
.ReleaseBuffer();
1155 GetApplicationString(ItemInfo
->hSubKey
, L
"Comments", szText
);
1156 ListView_SetItemText(hListView
, Index
, 2, szText
.GetBuffer());
1157 szText
.ReleaseBuffer();
1161 static BOOL CALLBACK
s_EnumAvailableAppProc(PAPPLICATION_INFO Info
)
1165 ATL::CStringW szIconPath
;
1166 HIMAGELIST hImageListView
= ListView_GetImageList(hListView
, LVSIL_SMALL
);
1168 if (!SearchPatternMatch(Info
->szName
, szSearchPattern
) &&
1169 !SearchPatternMatch(Info
->szDesc
, szSearchPattern
))
1174 if (GetStorageDirectory(szIconPath
))
1176 /* Load icon from file */
1177 szIconPath
+= L
"\\rapps\\icons\\" + Info
->szName
+ L
".ico";
1178 hIcon
= (HICON
) LoadImageW(NULL
,
1179 szIconPath
.GetString(),
1188 /* Load default icon */
1189 hIcon
= (HICON
) LoadIcon(hInst
, MAKEINTRESOURCEW(IDI_MAIN
));
1191 Index
= ImageList_AddIcon(hImageListView
, hIcon
);
1194 Index
= ListViewAddItem(Info
->Category
, Index
, Info
->szName
, (LPARAM
) Info
);
1195 hImageListView
= ListView_SetImageList(hListView
, hImageListView
, LVSIL_SMALL
);
1197 ListView_SetItemText(hListView
, Index
, 1, Info
->szVersion
.GetBuffer());
1198 Info
->szVersion
.ReleaseBuffer();
1200 ListView_SetItemText(hListView
, Index
, 2, Info
->szDesc
.GetBuffer());
1201 Info
->szDesc
.ReleaseBuffer();
1206 VOID
UpdateApplicationsList(INT EnumType
)
1208 ATL::CStringW szBuffer1
, szBuffer2
;
1209 HIMAGELIST hImageListView
= NULL
;
1211 m_ListView
->SendMessage(WM_SETREDRAW
, FALSE
, 0);
1213 if (EnumType
< 0) EnumType
= SelectedEnumType
;
1215 if (IS_INSTALLED_ENUM(SelectedEnumType
))
1216 FreeInstalledAppList();
1218 (VOID
) ListView_DeleteAllItems(hListView
);
1219 /* Create new ImageList */
1220 hImageListView
= ImageList_Create(LISTVIEW_ICON_SIZE
,
1222 GetSystemColorDepth() | ILC_MASK
,
1224 hImageListView
= ListView_SetImageList(hListView
, hImageListView
, LVSIL_SMALL
);
1227 ImageList_Destroy(hImageListView
);
1229 if (IS_AVAILABLE_ENUM(EnumType
))
1231 /* Enum available applications */
1232 EnumAvailableApplications(EnumType
, s_EnumAvailableAppProc
);
1235 SelectedEnumType
= EnumType
;
1237 szBuffer2
.LoadStringW(hInst
, IDS_APPS_COUNT
);
1238 szBuffer1
.Format(szBuffer2
, ListView_GetItemCount(hListView
));
1239 SetStatusBarText(szBuffer1
);
1243 /* set automatic column width for program names if the list is not empty */
1244 if (ListView_GetItemCount(hListView
) > 0)
1245 ListView_SetColumnWidth(hListView
, 0, LVSCW_AUTOSIZE
);
1247 SendMessage(hListView
, WM_SETREDRAW
, TRUE
, 0);
1251 static ATL::CWndClassInfo
& GetWndClassInfo()
1253 DWORD csStyle
= CS_VREDRAW
| CS_HREDRAW
;
1254 static ATL::CWndClassInfo wc
=
1256 { sizeof(WNDCLASSEX
), csStyle
, StartWindowProc
,
1258 LoadIcon(_AtlBaseModule
.GetModuleInstance(), MAKEINTRESOURCE(IDI_MAIN
)),
1259 LoadCursor(NULL
, IDC_ARROW
),
1260 (HBRUSH
) (COLOR_BTNFACE
+ 1), MAKEINTRESOURCE(IDR_MAINMENU
),
1261 L
"RAppsWnd", NULL
},
1262 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
1269 ATL::CStringW szWindowName
;
1270 szWindowName
.LoadStringW(hInst
, IDS_APPTITLE
);
1273 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Left
: CW_USEDEFAULT
),
1274 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Top
: CW_USEDEFAULT
),
1275 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Width
: 680),
1276 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Height
: 450)
1281 return CWindowImpl::Create(NULL
, r
, szWindowName
.GetString(), WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
, WS_EX_WINDOWEDGE
);
1284 CStatusBar
* GetStatusBar()
1289 CAppsListView
* GetListView()
1294 CRichEdit
* GetRichEdit()
1300 CMainWindow
* g_MainWindow
;
1302 HWND
CreateMainWindow()
1304 g_MainWindow
= new CMainWindow();
1305 return g_MainWindow
->Create();
1308 DWORD_PTR
ListViewGetlParam(INT item
)
1312 item
= g_MainWindow
->GetListView()->GetSelectionMark();
1314 return g_MainWindow
->GetListView()->GetItemData(item
);
1317 VOID
SetStatusBarText(LPCWSTR szText
)
1319 g_MainWindow
->GetStatusBar()->SetText(szText
);
1322 INT
ListViewAddItem(INT ItemIndex
, INT IconIndex
, LPWSTR lpName
, LPARAM lParam
)
1324 return g_MainWindow
->GetListView()->AddItem(ItemIndex
, IconIndex
, lpName
, lParam
);
1327 VOID
NewRichEditText(LPCWSTR szText
, DWORD flags
)
1329 g_MainWindow
->GetRichEdit()->SetText(szText
, flags
);
1332 VOID
InsertRichEditText(LPCWSTR szText
, DWORD flags
)
1334 g_MainWindow
->GetRichEdit()->InsertText(szText
, flags
);
1337 /* ATL version of functions */
1338 VOID
SetStatusBarText(const ATL::CStringW
& szText
)
1340 SetStatusBarText(szText
.GetString());
1343 INT
ListViewAddItem(INT ItemIndex
, INT IconIndex
, ATL::CStringW
& Name
, LPARAM lParam
)
1345 INT result
= ListViewAddItem(ItemIndex
, IconIndex
, Name
.GetBuffer(), lParam
);
1346 Name
.ReleaseBuffer();
1350 VOID
NewRichEditText(const ATL::CStringW
& szText
, DWORD flags
)
1352 NewRichEditText(szText
.GetString(), flags
);
1355 VOID
InsertRichEditText(const ATL::CStringW
& szText
, DWORD flags
)
1357 InsertRichEditText(szText
.GetString(), flags
);