1 /* PROJECT: ReactOS CE Applications Manager
2 * LICENSE: GPL - See COPYING in the top level directory
3 * AUTHORS: David Quintana <gigaherz@gmail.com>
8 #include <shlobj_undoc.h>
9 #include <shlguid_undoc.h>
15 #include <shellutils.h>
20 #include "crichedit.h"
22 #define SEARCH_TIMER_ID 'SR'
24 HWND hListView
= NULL
;
27 public CUiWindow
< CToolbar
<> >
29 #define TOOLBAR_HEIGHT 24
31 WCHAR szInstallBtn
[MAX_STR_LEN
];
32 WCHAR szUninstallBtn
[MAX_STR_LEN
];
33 WCHAR szModifyBtn
[MAX_STR_LEN
];
35 VOID
AddImageToImageList(HIMAGELIST hImageList
, UINT ImageIndex
)
39 if (!(hImage
= (HICON
) LoadImage(hInst
,
40 MAKEINTRESOURCE(ImageIndex
),
46 /* TODO: Error message */
49 ImageList_AddIcon(hImageList
, hImage
);
53 HIMAGELIST
InitImageList(VOID
)
55 HIMAGELIST hImageList
;
57 /* Create the toolbar icon image list */
58 hImageList
= ImageList_Create(TOOLBAR_HEIGHT
,//GetSystemMetrics(SM_CXSMICON),
59 TOOLBAR_HEIGHT
,//GetSystemMetrics(SM_CYSMICON),
60 ILC_MASK
| GetSystemColorDepth(),
65 /* TODO: Error message */
69 AddImageToImageList(hImageList
, IDI_INSTALL
);
70 AddImageToImageList(hImageList
, IDI_UNINSTALL
);
71 AddImageToImageList(hImageList
, IDI_MODIFY
);
72 AddImageToImageList(hImageList
, IDI_REFRESH
);
73 AddImageToImageList(hImageList
, IDI_UPDATE_DB
);
74 AddImageToImageList(hImageList
, IDI_SETTINGS
);
75 AddImageToImageList(hImageList
, IDI_EXIT
);
81 VOID
OnGetDispInfo(LPTOOLTIPTEXT lpttt
)
83 UINT idButton
= (UINT
) lpttt
->hdr
.idFrom
;
88 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EXIT
);
92 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_INSTALL
);
96 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_UNINSTALL
);
100 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_MODIFY
);
104 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_SETTINGS
);
108 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH
);
112 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_UPDATE_DB
);
117 HWND
Create(HWND hwndParent
)
119 static TBBUTTON Buttons
[] =
120 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
121 { 0, ID_INSTALL
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szInstallBtn
},
122 { 1, ID_UNINSTALL
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szUninstallBtn
},
123 { 2, ID_MODIFY
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szModifyBtn
},
124 { 5, 0, TBSTATE_ENABLED
, BTNS_SEP
, { 0 }, 0, 0 },
125 { 3, ID_REFRESH
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
126 { 4, ID_RESETDB
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, {0}, 0, 0},
127 { 5, 0, TBSTATE_ENABLED
, BTNS_SEP
, { 0 }, 0, 0 },
128 { 5, ID_SETTINGS
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
129 { 6, ID_EXIT
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 }
132 INT NumButtons
= _countof(Buttons
);
133 HIMAGELIST hImageList
;
135 LoadStringW(hInst
, IDS_INSTALL
, szInstallBtn
, _countof(szInstallBtn
));
136 LoadStringW(hInst
, IDS_UNINSTALL
, szUninstallBtn
, _countof(szUninstallBtn
));
137 LoadStringW(hInst
, IDS_MODIFY
, szModifyBtn
, _countof(szModifyBtn
));
139 m_hWnd
= CreateWindowExW(0,
142 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
| TBSTYLE_LIST
,
151 /* TODO: Show error message */
155 SendMessageW(TB_SETEXTENDEDSTYLE
, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
156 SetButtonStructSize();
158 hImageList
= InitImageList();
162 /* TODO: Show error message */
166 ImageList_Destroy((HIMAGELIST
) SetImageList(hImageList
));
168 AddButtons(NumButtons
, Buttons
);
174 class CAppsListView
:
175 public CUiWindow
<CListView
>
191 VOID
ColumnClick(LPNMLISTVIEW pnmv
)
193 SortContext ctx
= { this, pnmv
->iSubItem
};
195 SortItems(s_CompareFunc
, &ctx
);
197 bAscending
= !bAscending
;
200 PVOID
GetLParam(INT Index
)
207 ItemIndex
= (INT
) SendMessage(LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
216 ZeroMemory(&Item
, sizeof(Item
));
218 Item
.mask
= LVIF_PARAM
;
219 Item
.iItem
= ItemIndex
;
223 return (PVOID
) Item
.lParam
;
226 BOOL
AddColumn(INT Index
, LPWSTR lpText
, INT Width
, INT Format
)
230 ZeroMemory(&Column
, sizeof(Column
));
232 Column
.mask
= LVCF_FMT
| LVCF_TEXT
| LVCF_WIDTH
| LVCF_SUBITEM
;
233 Column
.iSubItem
= Index
;
234 Column
.pszText
= (LPTSTR
) lpText
;
238 return (InsertColumn(Index
, &Column
) == -1) ? FALSE
: TRUE
;
241 INT
AddItem(INT ItemIndex
, INT IconIndex
, LPWSTR lpText
, LPARAM lParam
)
245 ZeroMemory(&Item
, sizeof(Item
));
247 Item
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
248 Item
.pszText
= lpText
;
249 Item
.lParam
= lParam
;
250 Item
.iItem
= ItemIndex
;
251 Item
.iImage
= IconIndex
;
253 return InsertItem(&Item
);
256 static INT CALLBACK
s_CompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
258 SortContext
* ctx
= ((SortContext
*) lParamSort
);
259 return ctx
->lvw
->CompareFunc(lParam1
, lParam2
, ctx
->iSubItem
);
262 INT
CompareFunc(LPARAM lParam1
, LPARAM lParam2
, INT iSubItem
)
264 WCHAR Item1
[MAX_STR_LEN
], Item2
[MAX_STR_LEN
];
265 LVFINDINFO IndexInfo
;
268 IndexInfo
.flags
= LVFI_PARAM
;
270 IndexInfo
.lParam
= lParam1
;
271 Index
= FindItem(-1, &IndexInfo
);
272 GetItemText(Index
, iSubItem
, Item1
, _countof(Item1
));
274 IndexInfo
.lParam
= lParam2
;
275 Index
= FindItem(-1, &IndexInfo
);
276 GetItemText(Index
, iSubItem
, Item2
, _countof(Item2
));
279 return wcscmp(Item2
, Item1
);
281 return wcscmp(Item1
, Item2
);
286 HWND
Create(HWND hwndParent
)
288 RECT r
= { 205, 28, 465, 250 };
289 DWORD style
= WS_CHILD
| WS_VISIBLE
| LVS_SORTASCENDING
| LVS_REPORT
| LVS_SINGLESEL
| LVS_SHOWSELALWAYS
;
290 HMENU menu
= GetSubMenu(LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_APPLICATIONMENU
)), 0);
292 HWND hwnd
= CListView::Create(hwndParent
, r
, NULL
, style
, WS_EX_CLIENTEDGE
, menu
);
295 SetExtendedListViewStyle(LVS_EX_FULLROWSELECT
);
303 public CWindowImpl
<CMainWindow
, CWindow
, CFrameWinTraits
>
305 CUiPanel
* m_ClientPanel
;
306 CUiSplitPanel
* m_VSplitter
;
307 CUiSplitPanel
* m_HSplitter
;
309 CMainToolbar
* m_Toolbar
;
310 CAppsListView
* m_ListView
;
312 CUiWindow
<CTreeView
> * m_TreeView
;
313 CUiWindow
<CStatusBar
> * m_StatusBar
;
314 CUiWindow
<CRichEdit
> * m_RichEdit
;
316 CUiWindow
<> * m_SearchBar
;
318 HIMAGELIST hImageTreeView
;
327 hImageTreeView(NULL
),
335 VOID
InitApplicationsList(VOID
)
337 WCHAR szText
[MAX_STR_LEN
];
339 /* Add columns to ListView */
340 LoadStringW(hInst
, IDS_APP_NAME
, szText
, _countof(szText
));
341 m_ListView
->AddColumn(0, szText
, 200, LVCFMT_LEFT
);
343 LoadStringW(hInst
, IDS_APP_INST_VERSION
, szText
, _countof(szText
));
344 m_ListView
->AddColumn(1, szText
, 90, LVCFMT_RIGHT
);
346 LoadStringW(hInst
, IDS_APP_DESCRIPTION
, szText
, _countof(szText
));
347 m_ListView
->AddColumn(3, szText
, 250, LVCFMT_LEFT
);
349 UpdateApplicationsList(ENUM_ALL_COMPONENTS
);
352 HTREEITEM
AddCategory(HTREEITEM hRootItem
, UINT TextIndex
, UINT IconIndex
)
354 WCHAR szText
[MAX_STR_LEN
];
358 hIcon
= (HICON
) LoadImage(hInst
,
359 MAKEINTRESOURCE(IconIndex
),
363 LR_CREATEDIBSECTION
);
365 Index
= ImageList_AddIcon(hImageTreeView
, hIcon
);
368 LoadStringW(hInst
, TextIndex
, szText
, _countof(szText
));
370 return m_TreeView
->AddItem(hRootItem
, szText
, Index
, Index
, TextIndex
);
373 VOID
InitCategoriesList(VOID
)
375 HTREEITEM hRootItem1
, hRootItem2
;
377 hRootItem1
= AddCategory(TVI_ROOT
, IDS_INSTALLED
, IDI_CATEGORY
);
378 AddCategory(hRootItem1
, IDS_APPLICATIONS
, IDI_APPS
);
379 AddCategory(hRootItem1
, IDS_UPDATES
, IDI_APPUPD
);
381 hRootItem2
= AddCategory(TVI_ROOT
, IDS_AVAILABLEFORINST
, IDI_CATEGORY
);
382 AddCategory(hRootItem2
, IDS_CAT_AUDIO
, IDI_CAT_AUDIO
);
383 AddCategory(hRootItem2
, IDS_CAT_VIDEO
, IDI_CAT_VIDEO
);
384 AddCategory(hRootItem2
, IDS_CAT_GRAPHICS
, IDI_CAT_GRAPHICS
);
385 AddCategory(hRootItem2
, IDS_CAT_GAMES
, IDI_CAT_GAMES
);
386 AddCategory(hRootItem2
, IDS_CAT_INTERNET
, IDI_CAT_INTERNET
);
387 AddCategory(hRootItem2
, IDS_CAT_OFFICE
, IDI_CAT_OFFICE
);
388 AddCategory(hRootItem2
, IDS_CAT_DEVEL
, IDI_CAT_DEVEL
);
389 AddCategory(hRootItem2
, IDS_CAT_EDU
, IDI_CAT_EDU
);
390 AddCategory(hRootItem2
, IDS_CAT_ENGINEER
, IDI_CAT_ENGINEER
);
391 AddCategory(hRootItem2
, IDS_CAT_FINANCE
, IDI_CAT_FINANCE
);
392 AddCategory(hRootItem2
, IDS_CAT_SCIENCE
, IDI_CAT_SCIENCE
);
393 AddCategory(hRootItem2
, IDS_CAT_TOOLS
, IDI_CAT_TOOLS
);
394 AddCategory(hRootItem2
, IDS_CAT_DRIVERS
, IDI_CAT_DRIVERS
);
395 AddCategory(hRootItem2
, IDS_CAT_LIBS
, IDI_CAT_LIBS
);
396 AddCategory(hRootItem2
, IDS_CAT_OTHER
, IDI_CAT_OTHER
);
398 m_TreeView
->SetImageList(hImageTreeView
, TVSIL_NORMAL
);
399 m_TreeView
->Expand(hRootItem2
, TVE_EXPAND
);
400 m_TreeView
->Expand(hRootItem1
, TVE_EXPAND
);
401 m_TreeView
->SelectItem(hRootItem1
);
404 BOOL
CreateStatusBar()
406 m_StatusBar
= new CUiWindow
<CStatusBar
>();
407 m_StatusBar
->m_VerticalAlignment
= UiAlign_RightBtm
;
408 m_StatusBar
->m_HorizontalAlignment
= UiAlign_Stretch
;
409 m_ClientPanel
->Children().Append(m_StatusBar
);
411 return m_StatusBar
->Create(m_hWnd
, (HMENU
)IDC_STATUSBAR
) != NULL
;
416 m_Toolbar
= new CMainToolbar();
417 m_Toolbar
->m_VerticalAlignment
= UiAlign_LeftTop
;
418 m_Toolbar
->m_HorizontalAlignment
= UiAlign_Stretch
;
419 m_ClientPanel
->Children().Append(m_Toolbar
);
421 return m_Toolbar
->Create(m_hWnd
) != NULL
;
424 BOOL
CreateTreeView()
426 m_TreeView
= new CUiWindow
<CTreeView
>();
427 m_TreeView
->m_VerticalAlignment
= UiAlign_Stretch
;
428 m_TreeView
->m_HorizontalAlignment
= UiAlign_Stretch
;
429 m_VSplitter
->First().Append(m_TreeView
);
431 return m_TreeView
->Create(m_hWnd
) != NULL
;
434 BOOL
CreateListView()
436 m_ListView
= new CAppsListView();
437 m_ListView
->m_VerticalAlignment
= UiAlign_Stretch
;
438 m_ListView
->m_HorizontalAlignment
= UiAlign_Stretch
;
439 m_HSplitter
->First().Append(m_ListView
);
441 hListView
= m_ListView
->Create(m_hWnd
);
442 return hListView
!= NULL
;
445 BOOL
CreateRichEdit()
447 m_RichEdit
= new CUiWindow
<CRichEdit
>();
448 m_RichEdit
->m_VerticalAlignment
= UiAlign_Stretch
;
449 m_RichEdit
->m_HorizontalAlignment
= UiAlign_Stretch
;
450 m_HSplitter
->Second().Append(m_RichEdit
);
452 return m_RichEdit
->Create(m_hWnd
) != NULL
;
455 BOOL
CreateVSplitter()
457 m_VSplitter
= new CUiSplitPanel();
458 m_VSplitter
->m_VerticalAlignment
= UiAlign_Stretch
;
459 m_VSplitter
->m_HorizontalAlignment
= UiAlign_Stretch
;
460 m_VSplitter
->m_DynamicFirst
= FALSE
;
461 m_VSplitter
->m_Horizontal
= FALSE
;
462 m_VSplitter
->m_MinFirst
= 240;
463 m_VSplitter
->m_MinSecond
= 300;
464 m_ClientPanel
->Children().Append(m_VSplitter
);
466 return m_VSplitter
->Create(m_hWnd
) != NULL
;
469 BOOL
CreateHSplitter()
471 m_HSplitter
= new CUiSplitPanel();
472 m_HSplitter
->m_VerticalAlignment
= UiAlign_Stretch
;
473 m_HSplitter
->m_HorizontalAlignment
= UiAlign_Stretch
;
474 m_HSplitter
->m_DynamicFirst
= TRUE
;
475 m_HSplitter
->m_Horizontal
= TRUE
;
476 m_HSplitter
->m_Pos
= 32768;
477 m_HSplitter
->m_MinFirst
= 300;
478 m_HSplitter
->m_MinSecond
= 80;
479 m_VSplitter
->Second().Append(m_HSplitter
);
481 return m_HSplitter
->Create(m_hWnd
) != NULL
;
484 BOOL
CreateSearchBar(VOID
)
486 WCHAR szBuf
[MAX_STR_LEN
];
489 m_SearchBar
= new CUiWindow
<>();
490 m_SearchBar
->m_VerticalAlignment
= UiAlign_LeftTop
;
491 m_SearchBar
->m_HorizontalAlignment
= UiAlign_RightBtm
;
492 m_SearchBar
->m_Margin
.top
= 6;
493 m_SearchBar
->m_Margin
.right
= 6;
494 //m_ClientPanel->Children().Append(m_SearchBar);
496 HWND hwnd
= CreateWindowExW(WS_EX_CLIENTEDGE
,
499 WS_CHILD
| WS_VISIBLE
| ES_LEFT
| ES_AUTOHSCROLL
,
509 m_SearchBar
->m_hWnd
= hwnd
;
511 m_SearchBar
->SendMessageW(WM_SETFONT
, (WPARAM
) GetStockObject(DEFAULT_GUI_FONT
), 0);
513 LoadStringW(hInst
, IDS_SEARCH_TEXT
, szBuf
, _countof(szBuf
));
514 m_SearchBar
->SetWindowTextW(szBuf
);
523 m_ClientPanel
= new CUiPanel();
524 m_ClientPanel
->m_VerticalAlignment
= UiAlign_Stretch
;
525 m_ClientPanel
->m_HorizontalAlignment
= UiAlign_Stretch
;
528 b
= b
&& CreateStatusBar();
529 b
= b
&& CreateToolbar();
530 b
= b
&& CreateSearchBar();
531 b
= b
&& CreateVSplitter();
534 b
= b
&& CreateHSplitter();
535 b
= b
&& CreateTreeView();
538 b
= b
&& CreateListView();
539 b
= b
&& CreateRichEdit();
546 /* Size status bar */
547 m_StatusBar
->SendMessage(WM_SIZE
, 0, 0);
550 m_Toolbar
->AutoSize();
552 ::GetWindowRect(m_Toolbar
->m_hWnd
, &rTop
);
553 ::GetWindowRect(m_StatusBar
->m_hWnd
, &rBottom
);
555 m_VSplitter
->m_Margin
.top
= rTop
.bottom
- rTop
.top
;
556 m_VSplitter
->m_Margin
.bottom
= rBottom
.bottom
-rBottom
.top
;
564 /* Create image list */
565 hImageTreeView
= ImageList_Create(TREEVIEW_ICON_SIZE
, TREEVIEW_ICON_SIZE
,
566 GetSystemColorDepth() | ILC_MASK
,
571 WCHAR szBuffer1
[MAX_STR_LEN
], szBuffer2
[MAX_STR_LEN
];
573 InitApplicationsList();
575 InitCategoriesList();
577 LoadStringW(hInst
, IDS_APPS_COUNT
, szBuffer2
, _countof(szBuffer2
));
578 StringCbPrintfW(szBuffer1
, sizeof(szBuffer1
),
580 m_ListView
->GetItemCount());
581 m_StatusBar
->SetText(szBuffer1
);
588 VOID
OnSize(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
590 /* Size status bar */
591 m_StatusBar
->SendMessage(WM_SIZE
, 0, 0);
594 m_Toolbar
->AutoSize();
597 RECT r
= { 0, 0, LOWORD(lParam
), HIWORD(lParam
) };
601 int count
= m_ClientPanel
->CountSizableChildren();
602 hdwp
= BeginDeferWindowPos(count
);
603 if (hdwp
) hdwp
= m_ClientPanel
->OnParentSize(r
, hdwp
);
604 if (hdwp
) EndDeferWindowPos(hdwp
);
606 // TODO: Sub-layouts for children of children
607 count
= m_SearchBar
->CountSizableChildren();
608 hdwp
= BeginDeferWindowPos(count
);
609 if (hdwp
) hdwp
= m_SearchBar
->OnParentSize(r
, hdwp
);
610 if (hdwp
) EndDeferWindowPos(hdwp
);
613 BOOL
ProcessWindowMessage(HWND hwnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, LRESULT
& theResult
, DWORD dwMapId
)
620 ::PostMessage(hwnd
, WM_CLOSE
, 0, 0);
630 FreeCachedAvailableEntries();
632 if (IS_INSTALLED_ENUM(SelectedEnumType
))
633 FreeInstalledAppList();
636 ImageList_Destroy(hImageTreeView
);
638 delete m_ClientPanel
;
645 OnCommand(wParam
, lParam
);
650 LPNMHDR data
= (LPNMHDR
) lParam
;
656 if (data
->hwndFrom
== m_TreeView
->m_hWnd
)
658 switch (((LPNMTREEVIEW
) lParam
)->itemNew
.lParam
)
661 UpdateApplicationsList(ENUM_ALL_COMPONENTS
);
664 case IDS_APPLICATIONS
:
665 UpdateApplicationsList(ENUM_APPLICATIONS
);
669 UpdateApplicationsList(ENUM_UPDATES
);
672 case IDS_AVAILABLEFORINST
:
673 UpdateApplicationsList(ENUM_ALL_AVAILABLE
);
677 UpdateApplicationsList(ENUM_CAT_AUDIO
);
681 UpdateApplicationsList(ENUM_CAT_DEVEL
);
684 case IDS_CAT_DRIVERS
:
685 UpdateApplicationsList(ENUM_CAT_DRIVERS
);
689 UpdateApplicationsList(ENUM_CAT_EDU
);
692 case IDS_CAT_ENGINEER
:
693 UpdateApplicationsList(ENUM_CAT_ENGINEER
);
696 case IDS_CAT_FINANCE
:
697 UpdateApplicationsList(ENUM_CAT_FINANCE
);
701 UpdateApplicationsList(ENUM_CAT_GAMES
);
704 case IDS_CAT_GRAPHICS
:
705 UpdateApplicationsList(ENUM_CAT_GRAPHICS
);
708 case IDS_CAT_INTERNET
:
709 UpdateApplicationsList(ENUM_CAT_INTERNET
);
713 UpdateApplicationsList(ENUM_CAT_LIBS
);
717 UpdateApplicationsList(ENUM_CAT_OFFICE
);
721 UpdateApplicationsList(ENUM_CAT_OTHER
);
724 case IDS_CAT_SCIENCE
:
725 UpdateApplicationsList(ENUM_CAT_SCIENCE
);
729 UpdateApplicationsList(ENUM_CAT_TOOLS
);
733 UpdateApplicationsList(ENUM_CAT_VIDEO
);
738 HMENU mainMenu
= ::GetMenu(hwnd
);
739 HMENU lvwMenu
= ::GetMenu(m_ListView
->m_hWnd
);
741 /* Disable/enable items based on treeview selection */
742 if (IsSelectedNodeInstalled())
744 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_ENABLED
);
745 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_GRAYED
);
746 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_ENABLED
);
747 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_ENABLED
);
749 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_ENABLED
);
750 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_GRAYED
);
751 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_ENABLED
);
752 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_ENABLED
);
754 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_REGREMOVE
, TRUE
);
755 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_INSTALL
, FALSE
);
756 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_UNINSTALL
, TRUE
);
757 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_MODIFY
, TRUE
);
761 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_GRAYED
);
762 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_ENABLED
);
763 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_GRAYED
);
764 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_GRAYED
);
766 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_GRAYED
);
767 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_ENABLED
);
768 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_GRAYED
);
769 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_GRAYED
);
771 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_REGREMOVE
, FALSE
);
772 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_INSTALL
, TRUE
);
773 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_UNINSTALL
, FALSE
);
774 m_Toolbar
->SendMessage(TB_ENABLEBUTTON
, ID_MODIFY
, FALSE
);
779 case LVN_ITEMCHANGED
:
781 LPNMLISTVIEW pnic
= (LPNMLISTVIEW
) lParam
;
783 if (pnic
->hdr
.hwndFrom
== m_ListView
->m_hWnd
)
785 /* Check if this is a valid item
786 * (technically, it can be also an unselect) */
787 INT ItemIndex
= pnic
->iItem
;
788 if (ItemIndex
== -1 ||
789 ItemIndex
>= ListView_GetItemCount(pnic
->hdr
.hwndFrom
))
794 /* Check if the focus has been moved to another item */
795 if ((pnic
->uChanged
& LVIF_STATE
) &&
796 (pnic
->uNewState
& LVIS_FOCUSED
) &&
797 !(pnic
->uOldState
& LVIS_FOCUSED
))
799 if (IS_INSTALLED_ENUM(SelectedEnumType
))
800 ShowInstalledAppInfo(ItemIndex
);
801 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
802 ShowAvailableAppInfo(ItemIndex
);
808 case LVN_COLUMNCLICK
:
810 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
) lParam
;
812 m_ListView
->ColumnClick(pnmv
);
818 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
820 if (IS_INSTALLED_ENUM(SelectedEnumType
))
821 ShowInstalledAppInfo(-1);
822 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
823 ShowAvailableAppInfo(-1);
830 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
832 /* this won't do anything if the program is already installed */
833 SendMessage(hwnd
, WM_COMMAND
, ID_INSTALL
, 0);
840 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
842 ShowPopupMenu(m_ListView
->m_hWnd
, 0, ID_INSTALL
);
848 OnLink((ENLINK
*) lParam
);
851 case TTN_GETDISPINFO
:
852 m_Toolbar
->OnGetDispInfo((LPTOOLTIPTEXT
) lParam
);
859 OnSize(hwnd
, wParam
, lParam
);
864 LPRECT pRect
= (LPRECT
) lParam
;
866 if (pRect
->right
- pRect
->left
< 565)
867 pRect
->right
= pRect
->left
+ 565;
869 if (pRect
->bottom
- pRect
->top
< 300)
870 pRect
->bottom
= pRect
->top
+ 300;
875 case WM_SYSCOLORCHANGE
:
877 /* Forward WM_SYSCOLORCHANGE to common controls */
878 m_ListView
->SendMessage(WM_SYSCOLORCHANGE
, 0, 0);
879 m_TreeView
->SendMessage(WM_SYSCOLORCHANGE
, 0, 0);
880 m_Toolbar
->SendMessage(WM_SYSCOLORCHANGE
, 0, 0);
881 m_ListView
->SendMessage(EM_SETBKGNDCOLOR
, 0, GetSysColor(COLOR_BTNFACE
));
886 if (wParam
== SEARCH_TIMER_ID
)
888 ::KillTimer(hwnd
, SEARCH_TIMER_ID
);
889 UpdateApplicationsList(-1);
897 virtual VOID
OnLink(ENLINK
*Link
)
904 if (pLink
) HeapFree(GetProcessHeap(), 0, pLink
);
906 pLink
= (PWSTR
) HeapAlloc(GetProcessHeap(), 0,
907 (max(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) -
908 min(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) + 1) * sizeof(WCHAR
));
911 /* TODO: Error message */
915 m_RichEdit
->SendMessageW(EM_SETSEL
, Link
->chrg
.cpMin
, Link
->chrg
.cpMax
);
916 m_RichEdit
->SendMessageW(EM_GETSELTEXT
, 0, (LPARAM
) pLink
);
918 ShowPopupMenu(m_RichEdit
->m_hWnd
, IDR_LINKMENU
, -1);
924 BOOL
IsSelectedNodeInstalled(void)
926 HTREEITEM hSelectedItem
= m_TreeView
->GetSelection();
929 tItem
.mask
= TVIF_PARAM
| TVIF_HANDLE
;
930 tItem
.hItem
= hSelectedItem
;
931 m_TreeView
->GetItem(&tItem
);
932 switch (tItem
.lParam
)
935 case IDS_APPLICATIONS
:
943 VOID
OnCommand(WPARAM wParam
, LPARAM lParam
)
945 WORD wCommand
= LOWORD(wParam
);
947 if (lParam
== (LPARAM
) m_SearchBar
->m_hWnd
)
949 WCHAR szBuf
[MAX_STR_LEN
];
951 switch (HIWORD(wParam
))
955 WCHAR szWndText
[MAX_STR_LEN
];
957 LoadStringW(hInst
, IDS_SEARCH_TEXT
, szBuf
, _countof(szBuf
));
958 m_SearchBar
->GetWindowTextW(szWndText
, MAX_STR_LEN
);
959 if (wcscmp(szBuf
, szWndText
) == 0)
961 SearchEnabled
= FALSE
;
962 m_SearchBar
->SetWindowTextW(L
"");
969 m_SearchBar
->GetWindowTextW(szBuf
, MAX_STR_LEN
);
970 if (wcslen(szBuf
) < 1)
972 LoadStringW(hInst
, IDS_SEARCH_TEXT
, szBuf
, _countof(szBuf
));
973 SearchEnabled
= FALSE
;
974 m_SearchBar
->SetWindowTextW(szBuf
);
981 WCHAR szWndText
[MAX_STR_LEN
];
985 SearchEnabled
= TRUE
;
989 LoadStringW(hInst
, IDS_SEARCH_TEXT
, szBuf
, _countof(szBuf
));
990 m_SearchBar
->GetWindowTextW(szWndText
, MAX_STR_LEN
);
991 if (wcscmp(szBuf
, szWndText
) != 0)
993 StringCbCopy(szSearchPattern
, sizeof(szSearchPattern
),
998 szSearchPattern
[0] = UNICODE_NULL
;
1002 SystemParametersInfo(SPI_GETMENUSHOWDELAY
, 0, &dwDelay
, 0);
1003 SetTimer(SEARCH_TIMER_ID
, dwDelay
);
1014 ShellExecuteW(m_hWnd
, L
"open", pLink
, NULL
, NULL
, SW_SHOWNOACTIVATE
);
1015 HeapFree(GetProcessHeap(), 0, pLink
);
1019 CopyTextToClipboard(pLink
);
1020 HeapFree(GetProcessHeap(), 0, pLink
);
1024 CreateSettingsDlg(m_hWnd
);
1028 PostMessageW(WM_CLOSE
, 0, 0);
1032 if (DownloadApplication(-1))
1033 /* TODO: Implement install dialog
1034 * if (InstallApplication(-1))
1036 UpdateApplicationsList(-1);
1040 if (UninstallApplication(-1, FALSE
))
1041 UpdateApplicationsList(-1);
1045 if (UninstallApplication(-1, TRUE
))
1046 UpdateApplicationsList(-1);
1050 RemoveAppFromRegistry(-1);
1054 UpdateApplicationsList(-1);
1059 UpdateApplicationsList(-1);
1063 MessageBoxW(L
"Help not implemented yet", NULL
, MB_OK
);
1072 VOID
FreeInstalledAppList(VOID
)
1074 INT Count
= ListView_GetItemCount(hListView
) - 1;
1075 PINSTALLED_INFO Info
;
1079 Info
= (PINSTALLED_INFO
) ListViewGetlParam(Count
);
1082 RegCloseKey(Info
->hSubKey
);
1083 HeapFree(GetProcessHeap(), 0, Info
);
1089 static BOOL
SearchPatternMatch(PCWSTR szHaystack
, PCWSTR szNeedle
)
1093 /* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
1094 return StrStrIW(szHaystack
, szNeedle
) != NULL
;
1097 static BOOL CALLBACK
s_EnumInstalledAppProc(INT ItemIndex
, LPWSTR lpName
, PINSTALLED_INFO Info
)
1099 PINSTALLED_INFO ItemInfo
;
1100 WCHAR szText
[MAX_PATH
];
1103 if (!SearchPatternMatch(lpName
, szSearchPattern
))
1105 RegCloseKey(Info
->hSubKey
);
1109 ItemInfo
= (PINSTALLED_INFO
) HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO
));
1112 RegCloseKey(Info
->hSubKey
);
1116 RtlCopyMemory(ItemInfo
, Info
, sizeof(INSTALLED_INFO
));
1118 Index
= ListViewAddItem(ItemIndex
, 0, lpName
, (LPARAM
) ItemInfo
);
1120 /* Get version info */
1121 GetApplicationString(ItemInfo
->hSubKey
, L
"DisplayVersion", szText
);
1122 ListView_SetItemText(hListView
, Index
, 1, szText
);
1125 GetApplicationString(ItemInfo
->hSubKey
, L
"Comments", szText
);
1126 ListView_SetItemText(hListView
, Index
, 2, szText
);
1131 static BOOL CALLBACK
s_EnumAvailableAppProc(PAPPLICATION_INFO Info
)
1135 if (!SearchPatternMatch(Info
->szName
, szSearchPattern
) &&
1136 !SearchPatternMatch(Info
->szDesc
, szSearchPattern
))
1141 /* Only add a ListView entry if...
1142 - no RegName was supplied (so we cannot determine whether the application is installed or not) or
1143 - a RegName was supplied and the application is not installed
1145 if (!*Info
->szRegName
|| (!IsInstalledApplication(Info
->szRegName
, FALSE
) && !IsInstalledApplication(Info
->szRegName
, TRUE
)))
1147 Index
= ListViewAddItem(Info
->Category
, 0, Info
->szName
, (LPARAM
) Info
);
1149 ListView_SetItemText(hListView
, Index
, 1, Info
->szVersion
);
1150 ListView_SetItemText(hListView
, Index
, 2, Info
->szDesc
);
1156 VOID
UpdateApplicationsList(INT EnumType
)
1158 WCHAR szBuffer1
[MAX_STR_LEN
], szBuffer2
[MAX_STR_LEN
];
1160 HIMAGELIST hImageListView
;
1162 m_ListView
->SendMessage(WM_SETREDRAW
, FALSE
, 0);
1164 if (EnumType
== -1) EnumType
= SelectedEnumType
;
1166 if (IS_INSTALLED_ENUM(SelectedEnumType
))
1167 FreeInstalledAppList();
1169 (VOID
) ListView_DeleteAllItems(hListView
);
1171 /* Create image list */
1172 hImageListView
= ImageList_Create(LISTVIEW_ICON_SIZE
,
1174 GetSystemColorDepth() | ILC_MASK
,
1177 hIcon
= (HICON
) LoadImage(hInst
,
1178 MAKEINTRESOURCE(IDI_MAIN
),
1182 LR_CREATEDIBSECTION
);
1184 ImageList_AddIcon(hImageListView
, hIcon
);
1187 if (IS_INSTALLED_ENUM(EnumType
))
1189 /* Enum installed applications and updates */
1190 EnumInstalledApplications(EnumType
, TRUE
, s_EnumInstalledAppProc
);
1191 EnumInstalledApplications(EnumType
, FALSE
, s_EnumInstalledAppProc
);
1193 else if (IS_AVAILABLE_ENUM(EnumType
))
1195 /* Enum available applications */
1196 EnumAvailableApplications(EnumType
, s_EnumAvailableAppProc
);
1199 /* Set image list for ListView */
1200 hImageListView
= ListView_SetImageList(hListView
, hImageListView
, LVSIL_SMALL
);
1202 /* Destroy old image list */
1204 ImageList_Destroy(hImageListView
);
1206 SelectedEnumType
= EnumType
;
1208 LoadStringW(hInst
, IDS_APPS_COUNT
, szBuffer2
, _countof(szBuffer2
));
1209 StringCbPrintfW(szBuffer1
, sizeof(szBuffer1
),
1211 ListView_GetItemCount(hListView
));
1212 SetStatusBarText(szBuffer1
);
1216 /* set automatic column width for program names if the list is not empty */
1217 if (ListView_GetItemCount(hListView
) > 0)
1218 ListView_SetColumnWidth(hListView
, 0, LVSCW_AUTOSIZE
);
1220 SendMessage(hListView
, WM_SETREDRAW
, TRUE
, 0);
1224 static ATL::CWndClassInfo
& GetWndClassInfo()
1226 DWORD csStyle
= CS_VREDRAW
|CS_HREDRAW
;
1227 static ATL::CWndClassInfo wc
=
1229 { sizeof(WNDCLASSEX
), csStyle
, StartWindowProc
,
1231 LoadIcon(_AtlBaseModule
.GetModuleInstance(), MAKEINTRESOURCE(IDI_MAIN
)),
1232 LoadCursor(NULL
, IDC_ARROW
),
1233 (HBRUSH
) (COLOR_BTNFACE
+ 1), MAKEINTRESOURCE(IDR_MAINMENU
),
1234 L
"RAppsWnd", NULL
},
1235 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
1242 WCHAR szWindowName
[MAX_STR_LEN
];
1244 LoadStringW(hInst
, IDS_APPTITLE
, szWindowName
, _countof(szWindowName
));
1247 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Left
: CW_USEDEFAULT
),
1248 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Top
: CW_USEDEFAULT
),
1249 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Width
: 680),
1250 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Height
: 450)
1255 return CWindowImpl::Create(NULL
, r
, szWindowName
, WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
, WS_EX_WINDOWEDGE
);
1258 CStatusBar
* GetStatusBar()
1263 CAppsListView
* GetListView()
1268 CRichEdit
* GetRichEdit()
1274 CMainWindow
* g_MainWindow
;
1276 HWND
CreateMainWindow()
1278 g_MainWindow
= new CMainWindow();
1279 return g_MainWindow
->Create();
1282 DWORD_PTR
ListViewGetlParam(INT item
)
1286 item
= g_MainWindow
->GetListView()->GetSelectionMark();
1288 return g_MainWindow
->GetListView()->GetItemData(item
);
1291 VOID
SetStatusBarText(PCWSTR szText
)
1293 g_MainWindow
->GetStatusBar()->SetText(szText
);
1296 INT
ListViewAddItem(INT ItemIndex
, INT IconIndex
, PWSTR lpName
, LPARAM lParam
)
1298 return g_MainWindow
->GetListView()->AddItem(ItemIndex
, IconIndex
, lpName
, lParam
);
1301 VOID
NewRichEditText(PCWSTR szText
, DWORD flags
)
1303 g_MainWindow
->GetRichEdit()->SetText(szText
, flags
);
1306 VOID
InsertRichEditText(PCWSTR szText
, DWORD flags
)
1308 g_MainWindow
->GetRichEdit()->InsertText(szText
, flags
);