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
) LoadImageW(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 LVFINDINFOW 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 SendMessageW(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();
629 RECT r
= {0, 0, LOWORD(lParam
), HIWORD(lParam
)};
631 int count
= m_ClientPanel
->CountSizableChildren();
633 hdwp
= BeginDeferWindowPos(count
);
636 hdwp
= m_ClientPanel
->OnParentSize(r
, hdwp
);
640 EndDeferWindowPos(hdwp
);
643 // TODO: Sub-layouts for children of children
644 count
= m_SearchBar
->CountSizableChildren();
645 hdwp
= BeginDeferWindowPos(count
);
648 hdwp
= m_SearchBar
->OnParentSize(r
, hdwp
);
652 EndDeferWindowPos(hdwp
);
656 BOOL
ProcessWindowMessage(HWND hwnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, LRESULT
& theResult
, DWORD dwMapId
)
663 ::PostMessage(hwnd
, WM_CLOSE
, 0, 0);
673 FreeCachedAvailableEntries();
675 if (IS_INSTALLED_ENUM(SelectedEnumType
))
676 FreeInstalledAppList();
678 delete m_ClientPanel
;
685 OnCommand(wParam
, lParam
);
690 LPNMHDR data
= (LPNMHDR
) lParam
;
696 if (data
->hwndFrom
== m_TreeView
->m_hWnd
)
698 switch (((LPNMTREEVIEW
) lParam
)->itemNew
.lParam
)
701 UpdateApplicationsList(ENUM_ALL_COMPONENTS
);
704 case IDS_APPLICATIONS
:
705 UpdateApplicationsList(ENUM_APPLICATIONS
);
709 UpdateApplicationsList(ENUM_UPDATES
);
712 case IDS_AVAILABLEFORINST
:
713 UpdateApplicationsList(ENUM_ALL_AVAILABLE
);
717 UpdateApplicationsList(ENUM_CAT_AUDIO
);
721 UpdateApplicationsList(ENUM_CAT_DEVEL
);
724 case IDS_CAT_DRIVERS
:
725 UpdateApplicationsList(ENUM_CAT_DRIVERS
);
729 UpdateApplicationsList(ENUM_CAT_EDU
);
732 case IDS_CAT_ENGINEER
:
733 UpdateApplicationsList(ENUM_CAT_ENGINEER
);
736 case IDS_CAT_FINANCE
:
737 UpdateApplicationsList(ENUM_CAT_FINANCE
);
741 UpdateApplicationsList(ENUM_CAT_GAMES
);
744 case IDS_CAT_GRAPHICS
:
745 UpdateApplicationsList(ENUM_CAT_GRAPHICS
);
748 case IDS_CAT_INTERNET
:
749 UpdateApplicationsList(ENUM_CAT_INTERNET
);
753 UpdateApplicationsList(ENUM_CAT_LIBS
);
757 UpdateApplicationsList(ENUM_CAT_OFFICE
);
761 UpdateApplicationsList(ENUM_CAT_OTHER
);
764 case IDS_CAT_SCIENCE
:
765 UpdateApplicationsList(ENUM_CAT_SCIENCE
);
769 UpdateApplicationsList(ENUM_CAT_TOOLS
);
773 UpdateApplicationsList(ENUM_CAT_VIDEO
);
778 HMENU mainMenu
= ::GetMenu(hwnd
);
779 HMENU lvwMenu
= ::GetMenu(m_ListView
->m_hWnd
);
781 /* Disable/enable items based on treeview selection */
782 if (IsSelectedNodeInstalled())
784 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_ENABLED
);
785 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_GRAYED
);
786 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_ENABLED
);
787 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_ENABLED
);
789 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_ENABLED
);
790 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_GRAYED
);
791 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_ENABLED
);
792 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_ENABLED
);
794 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_REGREMOVE
, TRUE
);
795 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_INSTALL
, FALSE
);
796 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_UNINSTALL
, TRUE
);
797 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_MODIFY
, TRUE
);
801 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_GRAYED
);
802 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_ENABLED
);
803 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_GRAYED
);
804 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_GRAYED
);
806 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_GRAYED
);
807 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_ENABLED
);
808 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_GRAYED
);
809 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_GRAYED
);
811 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_REGREMOVE
, FALSE
);
812 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_INSTALL
, TRUE
);
813 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_UNINSTALL
, FALSE
);
814 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_MODIFY
, FALSE
);
819 case LVN_ITEMCHANGED
:
821 LPNMLISTVIEW pnic
= (LPNMLISTVIEW
) lParam
;
823 if (pnic
->hdr
.hwndFrom
== m_ListView
->m_hWnd
)
825 /* Check if this is a valid item
826 * (technically, it can be also an unselect) */
827 INT ItemIndex
= pnic
->iItem
;
828 if (ItemIndex
== -1 ||
829 ItemIndex
>= ListView_GetItemCount(pnic
->hdr
.hwndFrom
))
834 /* Check if the focus has been moved to another item */
835 if ((pnic
->uChanged
& LVIF_STATE
) &&
836 (pnic
->uNewState
& LVIS_FOCUSED
) &&
837 !(pnic
->uOldState
& LVIS_FOCUSED
))
839 if (IS_INSTALLED_ENUM(SelectedEnumType
))
840 ShowInstalledAppInfo(ItemIndex
);
841 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
842 ShowAvailableAppInfo(ItemIndex
);
848 case LVN_COLUMNCLICK
:
850 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
) lParam
;
852 m_ListView
->ColumnClick(pnmv
);
858 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
860 if (IS_INSTALLED_ENUM(SelectedEnumType
))
861 ShowInstalledAppInfo(-1);
862 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
863 ShowAvailableAppInfo(-1);
870 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
872 /* this won't do anything if the program is already installed */
873 SendMessage(hwnd
, WM_COMMAND
, ID_INSTALL
, 0);
880 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
882 ShowPopupMenu(m_ListView
->m_hWnd
, 0, ID_INSTALL
);
888 OnLink((ENLINK
*) lParam
);
891 case TTN_GETDISPINFO
:
892 m_Toolbar
->OnGetDispInfo((LPTOOLTIPTEXT
) lParam
);
899 OnSize(hwnd
, wParam
, lParam
);
904 LPRECT pRect
= (LPRECT
) lParam
;
906 if (pRect
->right
- pRect
->left
< 565)
907 pRect
->right
= pRect
->left
+ 565;
909 if (pRect
->bottom
- pRect
->top
< 300)
910 pRect
->bottom
= pRect
->top
+ 300;
915 case WM_SYSCOLORCHANGE
:
917 /* Forward WM_SYSCOLORCHANGE to common controls */
918 m_ListView
->SendMessageW(WM_SYSCOLORCHANGE
, 0, 0);
919 m_TreeView
->SendMessageW(WM_SYSCOLORCHANGE
, 0, 0);
920 m_Toolbar
->SendMessageW(WM_SYSCOLORCHANGE
, 0, 0);
921 m_ListView
->SendMessageW(EM_SETBKGNDCOLOR
, 0, GetSysColor(COLOR_BTNFACE
));
926 if (wParam
== SEARCH_TIMER_ID
)
928 ::KillTimer(hwnd
, SEARCH_TIMER_ID
);
929 UpdateApplicationsList(-1);
937 virtual VOID
OnLink(ENLINK
*Link
)
944 if (pLink
) HeapFree(GetProcessHeap(), 0, pLink
);
946 pLink
= (LPWSTR
) HeapAlloc(GetProcessHeap(), 0,
947 (max(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) -
948 min(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) + 1) * sizeof(WCHAR
));
951 /* TODO: Error message */
955 m_RichEdit
->SendMessageW(EM_SETSEL
, Link
->chrg
.cpMin
, Link
->chrg
.cpMax
);
956 m_RichEdit
->SendMessageW(EM_GETSELTEXT
, 0, (LPARAM
) pLink
);
958 ShowPopupMenu(m_RichEdit
->m_hWnd
, IDR_LINKMENU
, -1);
964 BOOL
IsSelectedNodeInstalled(void)
966 HTREEITEM hSelectedItem
= m_TreeView
->GetSelection();
969 tItem
.mask
= TVIF_PARAM
| TVIF_HANDLE
;
970 tItem
.hItem
= hSelectedItem
;
971 m_TreeView
->GetItem(&tItem
);
972 switch (tItem
.lParam
)
975 case IDS_APPLICATIONS
:
983 VOID
OnCommand(WPARAM wParam
, LPARAM lParam
)
985 WORD wCommand
= LOWORD(wParam
);
987 if (lParam
== (LPARAM
) m_SearchBar
->m_hWnd
)
991 switch (HIWORD(wParam
))
995 ATL::CStringW szWndText
;
997 szBuf
.LoadStringW(hInst
, IDS_SEARCH_TEXT
);
998 m_SearchBar
->GetWindowTextW(szWndText
);
999 if (szBuf
== szWndText
)
1001 SearchEnabled
= FALSE
;
1002 m_SearchBar
->SetWindowTextW(L
"");
1009 m_SearchBar
->GetWindowTextW(szBuf
);
1010 if (szBuf
.IsEmpty())
1012 szBuf
.LoadStringW(hInst
, IDS_SEARCH_TEXT
);
1013 SearchEnabled
= FALSE
;
1014 m_SearchBar
->SetWindowTextW(szBuf
.GetString());
1021 ATL::CStringW szWndText
;
1025 SearchEnabled
= TRUE
;
1029 szBuf
.LoadStringW(hInst
, IDS_SEARCH_TEXT
);
1030 m_SearchBar
->GetWindowTextW(szWndText
);
1031 if (szBuf
== szWndText
)
1033 szSearchPattern
.Empty();
1037 szSearchPattern
= szWndText
;
1041 SystemParametersInfoW(SPI_GETMENUSHOWDELAY
, 0, &dwDelay
, 0);
1042 SetTimer(SEARCH_TIMER_ID
, dwDelay
);
1053 ShellExecuteW(m_hWnd
, L
"open", pLink
, NULL
, NULL
, SW_SHOWNOACTIVATE
);
1054 HeapFree(GetProcessHeap(), 0, pLink
);
1058 CopyTextToClipboard(pLink
);
1059 HeapFree(GetProcessHeap(), 0, pLink
);
1063 CreateSettingsDlg(m_hWnd
);
1067 PostMessageW(WM_CLOSE
, 0, 0);
1071 if (DownloadApplication(-1))
1072 /* TODO: Implement install dialog
1073 * if (InstallApplication(-1))
1075 UpdateApplicationsList(-1);
1079 if (UninstallApplication(-1, FALSE
))
1080 UpdateApplicationsList(-1);
1084 if (UninstallApplication(-1, TRUE
))
1085 UpdateApplicationsList(-1);
1089 RemoveAppFromRegistry(-1);
1093 UpdateApplicationsList(-1);
1098 UpdateApplicationsList(-1);
1102 MessageBoxW(L
"Help not implemented yet", NULL
, MB_OK
);
1111 VOID
FreeInstalledAppList(VOID
)
1113 INT Count
= ListView_GetItemCount(hListView
) - 1;
1114 PINSTALLED_INFO Info
;
1118 Info
= (PINSTALLED_INFO
) ListViewGetlParam(Count
);
1121 RegCloseKey(Info
->hSubKey
);
1128 static BOOL
SearchPatternMatch(PCWSTR szHaystack
, PCWSTR szNeedle
)
1132 /* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
1133 return StrStrIW(szHaystack
, szNeedle
) != NULL
;
1136 static BOOL CALLBACK
s_EnumInstalledAppProc(INT ItemIndex
, LPWSTR lpName
, PINSTALLED_INFO Info
)
1138 PINSTALLED_INFO ItemInfo
;
1139 ATL::CStringW szText
;
1142 if (!SearchPatternMatch(lpName
, szSearchPattern
))
1144 RegCloseKey(Info
->hSubKey
);
1148 ItemInfo
= (PINSTALLED_INFO
) HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO
));
1151 RegCloseKey(Info
->hSubKey
);
1155 RtlCopyMemory(ItemInfo
, Info
, sizeof(INSTALLED_INFO
));
1157 Index
= ListViewAddItem(ItemIndex
, 0, lpName
, (LPARAM
) ItemInfo
);
1159 /* Get version info */
1160 GetApplicationString(ItemInfo
->hSubKey
, L
"DisplayVersion", szText
);
1161 ListView_SetItemText(hListView
, Index
, 1, szText
.GetBuffer());
1162 szText
.ReleaseBuffer();
1165 GetApplicationString(ItemInfo
->hSubKey
, L
"Comments", szText
);
1166 ListView_SetItemText(hListView
, Index
, 2, szText
.GetBuffer());
1167 szText
.ReleaseBuffer();
1171 static BOOL CALLBACK
s_EnumAvailableAppProc(PAPPLICATION_INFO Info
)
1175 ATL::CStringW szIconPath
;
1176 HIMAGELIST hImageListView
= ListView_GetImageList(hListView
, LVSIL_SMALL
);
1178 if (!SearchPatternMatch(Info
->szName
, szSearchPattern
) &&
1179 !SearchPatternMatch(Info
->szDesc
, szSearchPattern
))
1184 if (GetStorageDirectory(szIconPath
))
1186 /* Load icon from file */
1187 szIconPath
+= L
"\\rapps\\icons\\" + Info
->szName
+ L
".ico";
1188 hIcon
= (HICON
) LoadImageW(NULL
,
1189 szIconPath
.GetString(),
1198 /* Load default icon */
1199 hIcon
= (HICON
) LoadIconW(hInst
, MAKEINTRESOURCEW(IDI_MAIN
));
1201 Index
= ImageList_AddIcon(hImageListView
, hIcon
);
1204 Index
= ListViewAddItem(Info
->Category
, Index
, Info
->szName
, (LPARAM
) Info
);
1205 hImageListView
= ListView_SetImageList(hListView
, hImageListView
, LVSIL_SMALL
);
1207 ListView_SetItemText(hListView
, Index
, 1, Info
->szVersion
.GetBuffer());
1208 Info
->szVersion
.ReleaseBuffer();
1210 ListView_SetItemText(hListView
, Index
, 2, Info
->szDesc
.GetBuffer());
1211 Info
->szDesc
.ReleaseBuffer();
1216 VOID
UpdateApplicationsList(INT EnumType
)
1218 ATL::CStringW szBuffer1
, szBuffer2
;
1219 HIMAGELIST hImageListView
= NULL
;
1221 m_ListView
->SendMessageW(WM_SETREDRAW
, FALSE
, 0);
1223 if (EnumType
< 0) EnumType
= SelectedEnumType
;
1225 if (IS_INSTALLED_ENUM(SelectedEnumType
))
1226 FreeInstalledAppList();
1228 (VOID
) ListView_DeleteAllItems(hListView
);
1229 /* Create new ImageList */
1230 hImageListView
= ImageList_Create(LISTVIEW_ICON_SIZE
,
1232 GetSystemColorDepth() | ILC_MASK
,
1234 hImageListView
= ListView_SetImageList(hListView
, hImageListView
, LVSIL_SMALL
);
1237 ImageList_Destroy(hImageListView
);
1239 if (IS_AVAILABLE_ENUM(EnumType
))
1241 /* Enum available applications */
1242 EnumAvailableApplications(EnumType
, s_EnumAvailableAppProc
);
1245 SelectedEnumType
= EnumType
;
1247 szBuffer2
.LoadStringW(hInst
, IDS_APPS_COUNT
);
1248 szBuffer1
.Format(szBuffer2
, ListView_GetItemCount(hListView
));
1249 SetStatusBarText(szBuffer1
);
1253 /* set automatic column width for program names if the list is not empty */
1254 if (ListView_GetItemCount(hListView
) > 0)
1255 ListView_SetColumnWidth(hListView
, 0, LVSCW_AUTOSIZE
);
1257 SendMessageW(hListView
, WM_SETREDRAW
, TRUE
, 0);
1261 static ATL::CWndClassInfo
& GetWndClassInfo()
1263 DWORD csStyle
= CS_VREDRAW
| CS_HREDRAW
;
1264 static ATL::CWndClassInfo wc
=
1273 LoadIconW(_AtlBaseModule
.GetModuleInstance(), MAKEINTRESOURCEW(IDI_MAIN
)),
1274 LoadCursorW(NULL
, IDC_ARROW
),
1275 (HBRUSH
) (COLOR_BTNFACE
+ 1),
1276 MAKEINTRESOURCEW(IDR_MAINMENU
),
1280 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
1287 ATL::CStringW szWindowName
;
1288 szWindowName
.LoadStringW(hInst
, IDS_APPTITLE
);
1291 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Left
: CW_USEDEFAULT
),
1292 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Top
: CW_USEDEFAULT
),
1293 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Width
: 680),
1294 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Height
: 450)
1299 return CWindowImpl::Create(NULL
, r
, szWindowName
.GetString(), WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
, WS_EX_WINDOWEDGE
);
1302 CStatusBar
* GetStatusBar()
1307 CAppsListView
* GetListView()
1312 CRichEdit
* GetRichEdit()
1318 CMainWindow
* g_MainWindow
;
1320 HWND
CreateMainWindow()
1322 g_MainWindow
= new CMainWindow();
1323 return g_MainWindow
->Create();
1326 DWORD_PTR
ListViewGetlParam(INT item
)
1330 item
= g_MainWindow
->GetListView()->GetSelectionMark();
1332 return g_MainWindow
->GetListView()->GetItemData(item
);
1335 VOID
SetStatusBarText(LPCWSTR szText
)
1337 g_MainWindow
->GetStatusBar()->SetText(szText
);
1340 INT
ListViewAddItem(INT ItemIndex
, INT IconIndex
, LPWSTR lpName
, LPARAM lParam
)
1342 return g_MainWindow
->GetListView()->AddItem(ItemIndex
, IconIndex
, lpName
, lParam
);
1345 VOID
NewRichEditText(LPCWSTR szText
, DWORD flags
)
1347 g_MainWindow
->GetRichEdit()->SetText(szText
, flags
);
1350 VOID
InsertRichEditText(LPCWSTR szText
, DWORD flags
)
1352 g_MainWindow
->GetRichEdit()->InsertText(szText
, flags
);
1355 /* ATL version of functions */
1356 VOID
SetStatusBarText(const ATL::CStringW
& szText
)
1358 SetStatusBarText(szText
.GetString());
1361 INT
ListViewAddItem(INT ItemIndex
, INT IconIndex
, ATL::CStringW
& Name
, LPARAM lParam
)
1363 INT result
= ListViewAddItem(ItemIndex
, IconIndex
, Name
.GetBuffer(), lParam
);
1364 Name
.ReleaseBuffer();
1368 VOID
NewRichEditText(const ATL::CStringW
& szText
, DWORD flags
)
1370 NewRichEditText(szText
.GetString(), flags
);
1373 VOID
InsertRichEditText(const ATL::CStringW
& szText
, DWORD flags
)
1375 InsertRichEditText(szText
.GetString(), flags
);