2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * FILE: base/applications/rapps/gui.cpp
5 * PURPOSE: GUI classes for RAPPS
6 * COPYRIGHT: Copyright 2015 David Quintana (gigaherz@gmail.com)
7 * Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
13 #include "crichedit.h"
15 #include <shlobj_undoc.h>
16 #include <shlguid_undoc.h>
22 #include <shellutils.h>
25 #define SEARCH_TIMER_ID 'SR'
26 #define LISTVIEW_ICON_SIZE 24
27 #define TREEVIEW_ICON_SIZE 24
29 HWND hListView
= NULL
;
31 INT
GetSystemColorDepth()
36 pDevMode
.dmSize
= sizeof(pDevMode
);
37 pDevMode
.dmDriverExtra
= 0;
39 if (!EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &pDevMode
))
41 /* TODO: Error message */
45 switch (pDevMode
.dmBitsPerPel
)
47 case 32: ColorDepth
= ILC_COLOR32
; break;
48 case 24: ColorDepth
= ILC_COLOR24
; break;
49 case 16: ColorDepth
= ILC_COLOR16
; break;
50 case 8: ColorDepth
= ILC_COLOR8
; break;
51 case 4: ColorDepth
= ILC_COLOR4
; break;
52 default: ColorDepth
= ILC_COLOR
; break;
58 class CAvailableAppView
60 static inline VOID
InsertTextAfterLoaded_RichEdit(UINT uStringID
,
61 const ATL::CStringW
& szText
,
65 ATL::CStringW szLoadedText
;
66 if (!szText
.IsEmpty() && szLoadedText
.LoadStringW(uStringID
))
68 InsertRichEditText(szLoadedText
, StringFlags
);
69 InsertRichEditText(szText
, TextFlags
);
73 static inline VOID
InsertLoadedTextNewl_RichEdit(UINT uStringID
,
76 ATL::CStringW szLoadedText
;
77 if (szLoadedText
.LoadStringW(uStringID
))
79 InsertRichEditText(L
"\n", 0);
80 InsertRichEditText(szLoadedText
, StringFlags
);
81 InsertRichEditText(L
"\n", 0);
85 static VOID
InsertVersionInfo_RichEdit(CAvailableApplicationInfo
* Info
)
87 if (Info
->IsInstalled())
89 if (Info
->HasInstalledVersion())
91 if (Info
->HasUpdate())
92 InsertLoadedTextNewl_RichEdit(IDS_STATUS_UPDATE_AVAILABLE
, CFE_ITALIC
);
94 InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED
, CFE_ITALIC
);
96 InsertTextAfterLoaded_RichEdit(IDS_AINFO_VERSION
, Info
->m_szInstalledVersion
, CFE_BOLD
, 0);
100 InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED
, CFE_ITALIC
);
105 InsertLoadedTextNewl_RichEdit(IDS_STATUS_NOTINSTALLED
, CFE_ITALIC
);
108 InsertTextAfterLoaded_RichEdit(IDS_AINFO_AVAILABLEVERSION
, Info
->m_szVersion
, CFE_BOLD
, 0);
111 static VOID
InsertLicenseInfo_RichEdit(CAvailableApplicationInfo
* Info
)
113 ATL::CStringW szLicense
;
114 switch (Info
->m_LicenseType
)
116 case LICENSE_OPENSOURCE
:
117 szLicense
.LoadStringW(IDS_LICENSE_OPENSOURCE
);
119 case LICENSE_FREEWARE
:
120 szLicense
.LoadStringW(IDS_LICENSE_FREEWARE
);
123 szLicense
.LoadStringW(IDS_LICENSE_TRIAL
);
126 InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE
, Info
->m_szLicense
, CFE_BOLD
, 0);
130 szLicense
+= L
" (" + Info
->m_szLicense
+ L
")";
131 InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE
, szLicense
, CFE_BOLD
, 0);
134 static VOID
InsertLanguageInfo_RichEdit(CAvailableApplicationInfo
* Info
)
136 if (!Info
->HasLanguageInfo())
141 const INT nTranslations
= Info
->m_LanguageLCIDs
.GetSize();
142 ATL::CStringW szLangInfo
;
143 ATL::CStringW szLoadedTextAvailability
;
144 ATL::CStringW szLoadedAInfoText
;
146 szLoadedAInfoText
.LoadStringW(IDS_AINFO_LANGUAGES
);
148 if (Info
->HasNativeLanguage())
150 szLoadedTextAvailability
.LoadStringW(IDS_LANGUAGE_AVAILABLE_TRANSLATION
);
151 if (nTranslations
> 1)
154 buf
.LoadStringW(IDS_LANGUAGE_MORE_PLACEHOLDER
);
155 szLangInfo
.Format(buf
, nTranslations
- 1);
159 szLangInfo
.LoadStringW(IDS_LANGUAGE_SINGLE
);
160 szLangInfo
= L
" (" + szLangInfo
+ L
")";
163 else if (Info
->HasEnglishLanguage())
165 szLoadedTextAvailability
.LoadStringW(IDS_LANGUAGE_ENGLISH_TRANSLATION
);
166 if (nTranslations
> 1)
169 buf
.LoadStringW(IDS_LANGUAGE_AVAILABLE_PLACEHOLDER
);
170 szLangInfo
.Format(buf
, nTranslations
- 1);
174 szLangInfo
.LoadStringW(IDS_LANGUAGE_SINGLE
);
175 szLangInfo
= L
" (" + szLangInfo
+ L
")";
180 szLoadedTextAvailability
.LoadStringW(IDS_LANGUAGE_NO_TRANSLATION
);
183 InsertRichEditText(szLoadedAInfoText
, CFE_BOLD
);
184 InsertRichEditText(szLoadedTextAvailability
, NULL
);
185 InsertRichEditText(szLangInfo
, CFE_ITALIC
);
189 static BOOL
ShowAvailableAppInfo(INT Index
)
191 CAvailableApplicationInfo
* Info
= (CAvailableApplicationInfo
*) ListViewGetlParam(Index
);
192 if (!Info
) return FALSE
;
194 NewRichEditText(Info
->m_szName
, CFE_BOLD
);
195 InsertVersionInfo_RichEdit(Info
);
196 InsertLicenseInfo_RichEdit(Info
);
197 InsertLanguageInfo_RichEdit(Info
);
199 InsertTextAfterLoaded_RichEdit(IDS_AINFO_SIZE
, Info
->m_szSize
, CFE_BOLD
, 0);
200 InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLSITE
, Info
->m_szUrlSite
, CFE_BOLD
, CFE_LINK
);
201 InsertTextAfterLoaded_RichEdit(IDS_AINFO_DESCRIPTION
, Info
->m_szDesc
, CFE_BOLD
, 0);
202 InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLDOWNLOAD
, Info
->m_szUrlDownload
, CFE_BOLD
, CFE_LINK
);
209 public CUiWindow
< CToolbar
<> >
211 const INT m_iToolbarHeight
;
212 DWORD m_dButtonsWidthMax
;
214 WCHAR szInstallBtn
[MAX_STR_LEN
];
215 WCHAR szUninstallBtn
[MAX_STR_LEN
];
216 WCHAR szModifyBtn
[MAX_STR_LEN
];
217 WCHAR szSelectAll
[MAX_STR_LEN
];
219 VOID
AddImageToImageList(HIMAGELIST hImageList
, UINT ImageIndex
)
223 if (!(hImage
= (HICON
) LoadImageW(hInst
,
224 MAKEINTRESOURCE(ImageIndex
),
230 /* TODO: Error message */
233 ImageList_AddIcon(hImageList
, hImage
);
234 DeleteObject(hImage
);
237 HIMAGELIST
InitImageList()
239 HIMAGELIST hImageList
;
241 /* Create the toolbar icon image list */
242 hImageList
= ImageList_Create(m_iToolbarHeight
,//GetSystemMetrics(SM_CXSMICON),
243 m_iToolbarHeight
,//GetSystemMetrics(SM_CYSMICON),
244 ILC_MASK
| GetSystemColorDepth(),
248 /* TODO: Error message */
252 AddImageToImageList(hImageList
, IDI_INSTALL
);
253 AddImageToImageList(hImageList
, IDI_UNINSTALL
);
254 AddImageToImageList(hImageList
, IDI_MODIFY
);
255 AddImageToImageList(hImageList
, IDI_CHECK_ALL
);
256 AddImageToImageList(hImageList
, IDI_REFRESH
);
257 AddImageToImageList(hImageList
, IDI_UPDATE_DB
);
258 AddImageToImageList(hImageList
, IDI_SETTINGS
);
259 AddImageToImageList(hImageList
, IDI_EXIT
);
265 CMainToolbar() : m_iToolbarHeight(24)
269 VOID
OnGetDispInfo(LPTOOLTIPTEXT lpttt
)
271 UINT idButton
= (UINT
) lpttt
->hdr
.idFrom
;
276 lpttt
->lpszText
= MAKEINTRESOURCEW(IDS_TOOLTIP_EXIT
);
280 lpttt
->lpszText
= MAKEINTRESOURCEW(IDS_TOOLTIP_INSTALL
);
284 lpttt
->lpszText
= MAKEINTRESOURCEW(IDS_TOOLTIP_UNINSTALL
);
288 lpttt
->lpszText
= MAKEINTRESOURCEW(IDS_TOOLTIP_MODIFY
);
292 lpttt
->lpszText
= MAKEINTRESOURCEW(IDS_TOOLTIP_SETTINGS
);
296 lpttt
->lpszText
= MAKEINTRESOURCEW(IDS_TOOLTIP_REFRESH
);
300 lpttt
->lpszText
= MAKEINTRESOURCEW(IDS_TOOLTIP_UPDATE_DB
);
305 HWND
Create(HWND hwndParent
)
309 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
310 { 0, ID_INSTALL
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szInstallBtn
},
311 { 1, ID_UNINSTALL
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szUninstallBtn
},
312 { 2, ID_MODIFY
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szModifyBtn
},
313 { 3, ID_CHECK_ALL
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, (INT_PTR
) szSelectAll
},
314 { -1, 0, TBSTATE_ENABLED
, BTNS_SEP
, { 0 }, 0, 0 },
315 { 4, ID_REFRESH
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
316 { 5, ID_RESETDB
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
317 { -1, 0, TBSTATE_ENABLED
, BTNS_SEP
, { 0 }, 0, 0 },
318 { 6, ID_SETTINGS
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
319 { 7, ID_EXIT
, TBSTATE_ENABLED
, BTNS_BUTTON
| BTNS_AUTOSIZE
, { 0 }, 0, 0 },
322 LoadStringW(hInst
, IDS_INSTALL
, szInstallBtn
, _countof(szInstallBtn
));
323 LoadStringW(hInst
, IDS_UNINSTALL
, szUninstallBtn
, _countof(szUninstallBtn
));
324 LoadStringW(hInst
, IDS_MODIFY
, szModifyBtn
, _countof(szModifyBtn
));
325 LoadStringW(hInst
, IDS_SELECT_ALL
, szSelectAll
, _countof(szSelectAll
));
327 m_hWnd
= CreateWindowExW(0, TOOLBARCLASSNAMEW
, NULL
,
328 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
| TBSTYLE_LIST
,
335 /* TODO: Show error message */
339 SendMessageW(TB_SETEXTENDEDSTYLE
, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
340 SetButtonStructSize();
343 HIMAGELIST hImageList
= InitImageList();
347 /* TODO: Show error message */
351 ImageList_Destroy(SetImageList(hImageList
));
353 AddButtons(_countof(Buttons
), Buttons
);
355 /* Remember ideal width to use as a max width of buttons */
357 GetIdealSize(FALSE
, &size
);
358 m_dButtonsWidthMax
= size
.cx
;
363 VOID
HideButtonCaption()
365 DWORD dCurrentExStyle
= (DWORD
) SendMessageW(TB_GETEXTENDEDSTYLE
, 0, 0);
366 SendMessageW(TB_SETEXTENDEDSTYLE
, 0, dCurrentExStyle
| TBSTYLE_EX_MIXEDBUTTONS
);
369 VOID
ShowButtonCaption()
371 DWORD dCurrentExStyle
= (DWORD
) SendMessageW(TB_GETEXTENDEDSTYLE
, 0, 0);
372 SendMessageW(TB_SETEXTENDEDSTYLE
, 0, dCurrentExStyle
& ~TBSTYLE_EX_MIXEDBUTTONS
);
375 DWORD
GetMaxButtonsWidth() const
377 return m_dButtonsWidthMax
;
381 class CAppsListView
:
382 public CUiWindow
<CListView
>
398 bHasAllChecked(FALSE
),
400 bHasCheckboxes(FALSE
),
405 VOID
SetCheckboxesVisible(BOOL bIsVisible
)
409 SetExtendedListViewStyle(LVS_EX_CHECKBOXES
| LVS_EX_FULLROWSELECT
);
413 SetExtendedListViewStyle(LVS_EX_FULLROWSELECT
);
416 bHasCheckboxes
= bIsVisible
;
419 VOID
ColumnClick(LPNMLISTVIEW pnmv
)
423 INT nHeaderID
= pnmv
->iSubItem
;
425 if ((GetWindowLongPtr(GWL_STYLE
) & ~LVS_NOSORTHEADER
) == 0)
428 hHeader
= (HWND
) SendMessage(LVM_GETHEADER
, 0, 0);
429 ZeroMemory(&hColumn
, sizeof(hColumn
));
431 /* If the sorting column changed, remove the sorting style from the old column */
432 if ((nLastHeaderID
!= -1) && (nLastHeaderID
!= nHeaderID
))
434 hColumn
.mask
= HDI_FORMAT
;
435 Header_GetItem(hHeader
, nLastHeaderID
, &hColumn
);
436 hColumn
.fmt
&= ~(HDF_SORTUP
| HDF_SORTDOWN
);
437 Header_SetItem(hHeader
, nLastHeaderID
, &hColumn
);
440 /* Set the sorting style to the new column */
441 hColumn
.mask
= HDI_FORMAT
;
442 Header_GetItem(hHeader
, nHeaderID
, &hColumn
);
444 hColumn
.fmt
&= (bIsAscending
? ~HDF_SORTDOWN
: ~HDF_SORTUP
);
445 hColumn
.fmt
|= (bIsAscending
? HDF_SORTUP
: HDF_SORTDOWN
);
446 Header_SetItem(hHeader
, nHeaderID
, &hColumn
);
448 /* Sort the list, using the current values of nHeaderID and bIsAscending */
449 SortContext ctx
= {this, nHeaderID
};
450 SortItems(s_CompareFunc
, &ctx
);
452 /* Save new values */
453 nLastHeaderID
= nHeaderID
;
454 bIsAscending
= !bIsAscending
;
457 PVOID
GetLParam(INT Index
)
464 ItemIndex
= (INT
) SendMessage(LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
473 ZeroMemory(&Item
, sizeof(Item
));
475 Item
.mask
= LVIF_PARAM
;
476 Item
.iItem
= ItemIndex
;
480 return (PVOID
) Item
.lParam
;
483 BOOL
AddColumn(INT Index
, ATL::CStringW
& Text
, INT Width
, INT Format
)
485 return AddColumn(Index
, const_cast<LPWSTR
>(Text
.GetString()), Width
, Format
);
488 BOOL
AddColumn(INT Index
, LPWSTR lpText
, INT Width
, INT Format
)
492 ZeroMemory(&Column
, sizeof(Column
));
494 Column
.mask
= LVCF_FMT
| LVCF_TEXT
| LVCF_WIDTH
| LVCF_SUBITEM
;
495 Column
.iSubItem
= Index
;
496 Column
.pszText
= lpText
;
500 return (InsertColumn(Index
, &Column
) == -1) ? FALSE
: TRUE
;
503 INT
AddItem(INT ItemIndex
, INT IconIndex
, LPWSTR lpText
, LPARAM lParam
)
507 ZeroMemory(&Item
, sizeof(Item
));
509 Item
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
510 Item
.pszText
= lpText
;
511 Item
.lParam
= lParam
;
512 Item
.iItem
= ItemIndex
;
513 Item
.iImage
= IconIndex
;
515 return InsertItem(&Item
);
518 static INT CALLBACK
s_CompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
520 SortContext
* ctx
= ((SortContext
*) lParamSort
);
521 return ctx
->lvw
->CompareFunc(lParam1
, lParam2
, ctx
->iSubItem
);
524 INT
CompareFunc(LPARAM lParam1
, LPARAM lParam2
, INT iSubItem
)
526 ATL::CStringW Item1
, Item2
;
527 LVFINDINFOW IndexInfo
;
530 IndexInfo
.flags
= LVFI_PARAM
;
532 IndexInfo
.lParam
= lParam1
;
533 Index
= FindItem(-1, &IndexInfo
);
534 GetItemText(Index
, iSubItem
, Item1
.GetBuffer(MAX_STR_LEN
), MAX_STR_LEN
);
535 Item1
.ReleaseBuffer();
537 IndexInfo
.lParam
= lParam2
;
538 Index
= FindItem(-1, &IndexInfo
);
539 GetItemText(Index
, iSubItem
, Item2
.GetBuffer(MAX_STR_LEN
), MAX_STR_LEN
);
540 Item2
.ReleaseBuffer();
542 return bIsAscending
? Item1
.Compare(Item2
) : Item2
.Compare(Item1
);
545 HWND
Create(HWND hwndParent
)
547 RECT r
= {205, 28, 465, 250};
548 DWORD style
= WS_CHILD
| WS_VISIBLE
| LVS_SORTASCENDING
| LVS_REPORT
| LVS_SINGLESEL
| LVS_SHOWSELALWAYS
;
549 HMENU menu
= GetSubMenu(LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_APPLICATIONMENU
)), 0);
551 HWND hwnd
= CListView::Create(hwndParent
, r
, NULL
, style
, WS_EX_CLIENTEDGE
, menu
);
555 SetCheckboxesVisible(FALSE
);
561 BOOL
GetCheckState(INT item
)
563 return (BOOL
) (GetItemState(item
, LVIS_STATEIMAGEMASK
) >> 12) - 1;
566 VOID
SetCheckState(INT item
, BOOL fCheck
)
570 SetItemState(item
, INDEXTOSTATEIMAGEMASK((fCheck
) ? 2 : 1), LVIS_STATEIMAGEMASK
);
571 SetSelected(item
, fCheck
);
575 VOID
SetSelected(INT item
, BOOL value
)
579 for (INT i
= 0; i
>= 0; i
= GetNextItem(i
, LVNI_ALL
))
581 CAvailableApplicationInfo
* pAppInfo
= (CAvailableApplicationInfo
*) GetItemData(i
);
584 pAppInfo
->m_IsSelected
= value
;
590 CAvailableApplicationInfo
* pAppInfo
= (CAvailableApplicationInfo
*) GetItemData(item
);
593 pAppInfo
->m_IsSelected
= value
;
602 bHasAllChecked
= !bHasAllChecked
;
603 SetCheckState(-1, bHasAllChecked
);
607 ATL::CSimpleArray
<CAvailableApplicationInfo
> GetCheckedItems()
611 return ATL::CSimpleArray
<CAvailableApplicationInfo
>();
614 ATL::CSimpleArray
<CAvailableApplicationInfo
> list
;
615 for (INT i
= 0; i
>= 0; i
= GetNextItem(i
, LVNI_ALL
))
617 if (GetCheckState(i
) != FALSE
)
619 CAvailableApplicationInfo
* pAppInfo
= (CAvailableApplicationInfo
*) GetItemData(i
);
626 CAvailableApplicationInfo
* GetSelectedData()
628 INT item
= GetSelectionMark();
629 return (CAvailableApplicationInfo
*) GetItemData(item
);
633 class CSideTreeView
:
634 public CUiWindow
<CTreeView
>
636 HIMAGELIST hImageTreeView
;
641 hImageTreeView(ImageList_Create(TREEVIEW_ICON_SIZE
, TREEVIEW_ICON_SIZE
,
642 GetSystemColorDepth() | ILC_MASK
,
647 HTREEITEM
AddItem(HTREEITEM hParent
, ATL::CStringW
&Text
, INT Image
, INT SelectedImage
, LPARAM lParam
)
649 return CUiWindow
<CTreeView
>::AddItem(hParent
, const_cast<LPWSTR
>(Text
.GetString()), Image
, SelectedImage
, lParam
);
652 HTREEITEM
AddCategory(HTREEITEM hRootItem
, UINT TextIndex
, UINT IconIndex
)
654 ATL::CStringW szText
;
658 hIcon
= (HICON
) LoadImageW(hInst
,
659 MAKEINTRESOURCE(IconIndex
),
663 LR_CREATEDIBSECTION
);
666 Index
= ImageList_AddIcon(hImageTreeView
, hIcon
);
670 szText
.LoadStringW(TextIndex
);
671 return AddItem(hRootItem
, szText
, Index
, Index
, TextIndex
);
674 HIMAGELIST
SetImageList()
676 return CUiWindow
<CTreeView
>::SetImageList(hImageTreeView
, TVSIL_NORMAL
);
679 VOID
DestroyImageList()
682 ImageList_Destroy(hImageTreeView
);
698 CSearchBar() : m_Width(200), m_Height(22)
702 VOID
SetText(LPCWSTR lpszText
)
704 SendMessageW(SB_SETTEXT
, SBT_NOBORDERS
, (LPARAM
) lpszText
);
707 HWND
Create(HWND hwndParent
)
710 m_hWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, L
"Edit", NULL
,
711 WS_CHILD
| WS_VISIBLE
| ES_LEFT
| ES_AUTOHSCROLL
,
712 0, 0, m_Width
, m_Height
,
713 hwndParent
, (HMENU
) NULL
,
716 SendMessageW(WM_SETFONT
, (WPARAM
) GetStockObject(DEFAULT_GUI_FONT
), 0);
717 szBuf
.LoadStringW(IDS_SEARCH_TEXT
);
718 SetWindowTextW(szBuf
);
725 public CWindowImpl
<CMainWindow
, CWindow
, CFrameWinTraits
>
727 CUiPanel
* m_ClientPanel
;
728 CUiSplitPanel
* m_VSplitter
;
729 CUiSplitPanel
* m_HSplitter
;
731 CMainToolbar
* m_Toolbar
;
732 CAppsListView
* m_ListView
;
734 CSideTreeView
* m_TreeView
;
735 CUiWindow
<CStatusBar
>* m_StatusBar
;
736 CUiWindow
<CRichEdit
>* m_RichEdit
;
738 CUiWindow
<CSearchBar
>* m_SearchBar
;
739 CAvailableApps m_AvailableApps
;
752 bSearchEnabled(FALSE
)
757 VOID
InitApplicationsList()
759 ATL::CStringW szText
;
761 /* Add columns to ListView */
762 szText
.LoadStringW(IDS_APP_NAME
);
763 m_ListView
->AddColumn(0, szText
, 250, LVCFMT_LEFT
);
765 szText
.LoadStringW(IDS_APP_INST_VERSION
);
766 m_ListView
->AddColumn(1, szText
, 90, LVCFMT_RIGHT
);
768 szText
.LoadStringW(IDS_APP_DESCRIPTION
);
769 m_ListView
->AddColumn(3, szText
, 300, LVCFMT_LEFT
);
771 // Unnesesary since the list updates on every TreeView selection
772 // UpdateApplicationsList(ENUM_ALL_COMPONENTS);
775 HTREEITEM
AddCategory(HTREEITEM hRootItem
, UINT TextIndex
, UINT IconIndex
)
777 return m_TreeView
->AddCategory(hRootItem
, TextIndex
, IconIndex
);
780 VOID
InitCategoriesList()
782 HTREEITEM hRootItemInstalled
, hRootItemAvailable
;
784 hRootItemInstalled
= AddCategory(TVI_ROOT
, IDS_INSTALLED
, IDI_CATEGORY
);
785 AddCategory(hRootItemInstalled
, IDS_APPLICATIONS
, IDI_APPS
);
786 AddCategory(hRootItemInstalled
, IDS_UPDATES
, IDI_APPUPD
);
788 AddCategory(TVI_ROOT
, IDS_SELECTEDFORINST
, IDI_SELECTEDFORINST
);
790 hRootItemAvailable
= AddCategory(TVI_ROOT
, IDS_AVAILABLEFORINST
, IDI_CATEGORY
);
791 AddCategory(hRootItemAvailable
, IDS_CAT_AUDIO
, IDI_CAT_AUDIO
);
792 AddCategory(hRootItemAvailable
, IDS_CAT_VIDEO
, IDI_CAT_VIDEO
);
793 AddCategory(hRootItemAvailable
, IDS_CAT_GRAPHICS
, IDI_CAT_GRAPHICS
);
794 AddCategory(hRootItemAvailable
, IDS_CAT_GAMES
, IDI_CAT_GAMES
);
795 AddCategory(hRootItemAvailable
, IDS_CAT_INTERNET
, IDI_CAT_INTERNET
);
796 AddCategory(hRootItemAvailable
, IDS_CAT_OFFICE
, IDI_CAT_OFFICE
);
797 AddCategory(hRootItemAvailable
, IDS_CAT_DEVEL
, IDI_CAT_DEVEL
);
798 AddCategory(hRootItemAvailable
, IDS_CAT_EDU
, IDI_CAT_EDU
);
799 AddCategory(hRootItemAvailable
, IDS_CAT_ENGINEER
, IDI_CAT_ENGINEER
);
800 AddCategory(hRootItemAvailable
, IDS_CAT_FINANCE
, IDI_CAT_FINANCE
);
801 AddCategory(hRootItemAvailable
, IDS_CAT_SCIENCE
, IDI_CAT_SCIENCE
);
802 AddCategory(hRootItemAvailable
, IDS_CAT_TOOLS
, IDI_CAT_TOOLS
);
803 AddCategory(hRootItemAvailable
, IDS_CAT_DRIVERS
, IDI_CAT_DRIVERS
);
804 AddCategory(hRootItemAvailable
, IDS_CAT_LIBS
, IDI_CAT_LIBS
);
805 AddCategory(hRootItemAvailable
, IDS_CAT_THEMES
, IDI_CAT_THEMES
);
806 AddCategory(hRootItemAvailable
, IDS_CAT_OTHER
, IDI_CAT_OTHER
);
808 m_TreeView
->SetImageList();
809 m_TreeView
->Expand(hRootItemInstalled
, TVE_EXPAND
);
810 m_TreeView
->Expand(hRootItemAvailable
, TVE_EXPAND
);
811 m_TreeView
->SelectItem(hRootItemAvailable
);
814 BOOL
CreateStatusBar()
816 m_StatusBar
= new CUiWindow
<CStatusBar
>();
817 m_StatusBar
->m_VerticalAlignment
= UiAlign_RightBtm
;
818 m_StatusBar
->m_HorizontalAlignment
= UiAlign_Stretch
;
819 m_ClientPanel
->Children().Append(m_StatusBar
);
821 return m_StatusBar
->Create(m_hWnd
, (HMENU
) IDC_STATUSBAR
) != NULL
;
826 m_Toolbar
= new CMainToolbar();
827 m_Toolbar
->m_VerticalAlignment
= UiAlign_LeftTop
;
828 m_Toolbar
->m_HorizontalAlignment
= UiAlign_Stretch
;
829 m_ClientPanel
->Children().Append(m_Toolbar
);
831 return m_Toolbar
->Create(m_hWnd
) != NULL
;
834 BOOL
CreateTreeView()
836 m_TreeView
= new CSideTreeView();
837 m_TreeView
->m_VerticalAlignment
= UiAlign_Stretch
;
838 m_TreeView
->m_HorizontalAlignment
= UiAlign_Stretch
;
839 m_VSplitter
->First().Append(m_TreeView
);
841 return m_TreeView
->Create(m_hWnd
) != NULL
;
844 BOOL
CreateListView()
846 m_ListView
= new CAppsListView();
847 m_ListView
->m_VerticalAlignment
= UiAlign_Stretch
;
848 m_ListView
->m_HorizontalAlignment
= UiAlign_Stretch
;
849 m_HSplitter
->First().Append(m_ListView
);
851 hListView
= m_ListView
->Create(m_hWnd
);
852 return hListView
!= NULL
;
855 BOOL
CreateRichEdit()
857 m_RichEdit
= new CUiWindow
<CRichEdit
>();
858 m_RichEdit
->m_VerticalAlignment
= UiAlign_Stretch
;
859 m_RichEdit
->m_HorizontalAlignment
= UiAlign_Stretch
;
860 m_HSplitter
->Second().Append(m_RichEdit
);
862 return m_RichEdit
->Create(m_hWnd
) != NULL
;
865 BOOL
CreateVSplitter()
867 m_VSplitter
= new CUiSplitPanel();
868 m_VSplitter
->m_VerticalAlignment
= UiAlign_Stretch
;
869 m_VSplitter
->m_HorizontalAlignment
= UiAlign_Stretch
;
870 m_VSplitter
->m_DynamicFirst
= FALSE
;
871 m_VSplitter
->m_Horizontal
= FALSE
;
872 m_VSplitter
->m_MinFirst
= 0;
873 m_VSplitter
->m_MinSecond
= 320;
874 m_VSplitter
->m_Pos
= 240;
875 m_ClientPanel
->Children().Append(m_VSplitter
);
877 return m_VSplitter
->Create(m_hWnd
) != NULL
;
880 BOOL
CreateHSplitter()
882 m_HSplitter
= new CUiSplitPanel();
883 m_HSplitter
->m_VerticalAlignment
= UiAlign_Stretch
;
884 m_HSplitter
->m_HorizontalAlignment
= UiAlign_Stretch
;
885 m_HSplitter
->m_DynamicFirst
= TRUE
;
886 m_HSplitter
->m_Horizontal
= TRUE
;
887 m_HSplitter
->m_Pos
= INT_MAX
; //set INT_MAX to use lowest possible position (m_MinSecond)
888 m_HSplitter
->m_MinFirst
= 10;
889 m_HSplitter
->m_MinSecond
= 140;
890 m_VSplitter
->Second().Append(m_HSplitter
);
892 return m_HSplitter
->Create(m_hWnd
) != NULL
;
895 BOOL
CreateSearchBar()
897 m_SearchBar
= new CUiWindow
<CSearchBar
>();
898 m_SearchBar
->m_VerticalAlignment
= UiAlign_LeftTop
;
899 m_SearchBar
->m_HorizontalAlignment
= UiAlign_RightBtm
;
900 m_SearchBar
->m_Margin
.top
= 4;
901 m_SearchBar
->m_Margin
.right
= 6;
903 return m_SearchBar
->Create(m_Toolbar
->m_hWnd
) != NULL
;
911 m_ClientPanel
= new CUiPanel();
912 m_ClientPanel
->m_VerticalAlignment
= UiAlign_Stretch
;
913 m_ClientPanel
->m_HorizontalAlignment
= UiAlign_Stretch
;
916 b
= b
&& CreateStatusBar();
917 b
= b
&& CreateToolbar();
918 b
= b
&& CreateSearchBar();
919 b
= b
&& CreateVSplitter();
922 b
= b
&& CreateHSplitter();
923 b
= b
&& CreateTreeView();
926 b
= b
&& CreateListView();
927 b
= b
&& CreateRichEdit();
934 /* Size status bar */
935 m_StatusBar
->SendMessageW(WM_SIZE
, 0, 0);
938 m_Toolbar
->AutoSize();
940 ::GetWindowRect(m_Toolbar
->m_hWnd
, &rTop
);
941 ::GetWindowRect(m_StatusBar
->m_hWnd
, &rBottom
);
943 m_VSplitter
->m_Margin
.top
= rTop
.bottom
- rTop
.top
;
944 m_VSplitter
->m_Margin
.bottom
= rBottom
.bottom
- rBottom
.top
;
956 InitApplicationsList();
957 InitCategoriesList();
960 UpdateStatusBarText();
968 VOID
OnSize(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
970 if (wParam
== SIZE_MINIMIZED
)
973 /* Size status bar */
974 m_StatusBar
->SendMessage(WM_SIZE
, 0, 0);
977 m_Toolbar
->AutoSize();
979 /* Automatically hide captions */
980 DWORD dToolbarTreshold
= m_Toolbar
->GetMaxButtonsWidth();
981 DWORD dSearchbarMargin
= (LOWORD(lParam
) - m_SearchBar
->m_Width
);
983 if (dSearchbarMargin
> dToolbarTreshold
)
985 m_Toolbar
->ShowButtonCaption();
987 else if (dSearchbarMargin
< dToolbarTreshold
)
989 m_Toolbar
->HideButtonCaption();
992 RECT r
= {0, 0, LOWORD(lParam
), HIWORD(lParam
)};
994 INT count
= m_ClientPanel
->CountSizableChildren();
996 hdwp
= BeginDeferWindowPos(count
);
999 hdwp
= m_ClientPanel
->OnParentSize(r
, hdwp
);
1002 EndDeferWindowPos(hdwp
);
1007 // TODO: Sub-layouts for children of children
1008 count
= m_SearchBar
->CountSizableChildren();
1009 hdwp
= BeginDeferWindowPos(count
);
1012 hdwp
= m_SearchBar
->OnParentSize(r
, hdwp
);
1015 EndDeferWindowPos(hdwp
);
1021 BOOL
ProcessWindowMessage(HWND hwnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, LRESULT
& theResult
, DWORD dwMapId
)
1027 if (!InitControls())
1028 ::PostMessageW(hwnd
, WM_CLOSE
, 0, 0);
1033 ShowWindow(SW_HIDE
);
1037 m_AvailableApps
.FreeCachedEntries();
1039 if (IsInstalledEnum(SelectedEnumType
))
1040 FreeInstalledAppList();
1042 delete m_ClientPanel
;
1049 OnCommand(wParam
, lParam
);
1054 LPNMHDR data
= (LPNMHDR
) lParam
;
1058 case TVN_SELCHANGED
:
1060 if (data
->hwndFrom
== m_TreeView
->m_hWnd
)
1062 switch (((LPNMTREEVIEW
) lParam
)->itemNew
.lParam
)
1065 UpdateApplicationsList(ENUM_ALL_INSTALLED
);
1068 case IDS_APPLICATIONS
:
1069 UpdateApplicationsList(ENUM_INSTALLED_APPLICATIONS
);
1073 UpdateApplicationsList(ENUM_UPDATES
);
1076 case IDS_AVAILABLEFORINST
:
1077 UpdateApplicationsList(ENUM_ALL_AVAILABLE
);
1081 UpdateApplicationsList(ENUM_CAT_AUDIO
);
1085 UpdateApplicationsList(ENUM_CAT_DEVEL
);
1088 case IDS_CAT_DRIVERS
:
1089 UpdateApplicationsList(ENUM_CAT_DRIVERS
);
1093 UpdateApplicationsList(ENUM_CAT_EDU
);
1096 case IDS_CAT_ENGINEER
:
1097 UpdateApplicationsList(ENUM_CAT_ENGINEER
);
1100 case IDS_CAT_FINANCE
:
1101 UpdateApplicationsList(ENUM_CAT_FINANCE
);
1105 UpdateApplicationsList(ENUM_CAT_GAMES
);
1108 case IDS_CAT_GRAPHICS
:
1109 UpdateApplicationsList(ENUM_CAT_GRAPHICS
);
1112 case IDS_CAT_INTERNET
:
1113 UpdateApplicationsList(ENUM_CAT_INTERNET
);
1117 UpdateApplicationsList(ENUM_CAT_LIBS
);
1120 case IDS_CAT_OFFICE
:
1121 UpdateApplicationsList(ENUM_CAT_OFFICE
);
1125 UpdateApplicationsList(ENUM_CAT_OTHER
);
1128 case IDS_CAT_SCIENCE
:
1129 UpdateApplicationsList(ENUM_CAT_SCIENCE
);
1133 UpdateApplicationsList(ENUM_CAT_TOOLS
);
1137 UpdateApplicationsList(ENUM_CAT_VIDEO
);
1140 case IDS_CAT_THEMES
:
1141 UpdateApplicationsList(ENUM_CAT_THEMES
);
1144 case IDS_SELECTEDFORINST
:
1145 UpdateApplicationsList(ENUM_CAT_SELECTED
);
1150 HMENU mainMenu
= ::GetMenu(hwnd
);
1151 HMENU lvwMenu
= ::GetMenu(m_ListView
->m_hWnd
);
1153 /* Disable/enable items based on treeview selection */
1154 if (IsSelectedNodeInstalled())
1156 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_ENABLED
);
1157 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_GRAYED
);
1158 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_ENABLED
);
1159 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_ENABLED
);
1161 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_ENABLED
);
1162 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_GRAYED
);
1163 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_ENABLED
);
1164 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_ENABLED
);
1166 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_REGREMOVE
, TRUE
);
1167 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_INSTALL
, FALSE
);
1168 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_UNINSTALL
, TRUE
);
1169 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_MODIFY
, TRUE
);
1173 EnableMenuItem(mainMenu
, ID_REGREMOVE
, MF_GRAYED
);
1174 EnableMenuItem(mainMenu
, ID_INSTALL
, MF_ENABLED
);
1175 EnableMenuItem(mainMenu
, ID_UNINSTALL
, MF_GRAYED
);
1176 EnableMenuItem(mainMenu
, ID_MODIFY
, MF_GRAYED
);
1178 EnableMenuItem(lvwMenu
, ID_REGREMOVE
, MF_GRAYED
);
1179 EnableMenuItem(lvwMenu
, ID_INSTALL
, MF_ENABLED
);
1180 EnableMenuItem(lvwMenu
, ID_UNINSTALL
, MF_GRAYED
);
1181 EnableMenuItem(lvwMenu
, ID_MODIFY
, MF_GRAYED
);
1183 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_REGREMOVE
, FALSE
);
1184 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_INSTALL
, TRUE
);
1185 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_UNINSTALL
, FALSE
);
1186 m_Toolbar
->SendMessageW(TB_ENABLEBUTTON
, ID_MODIFY
, FALSE
);
1191 case LVN_ITEMCHANGED
:
1193 LPNMLISTVIEW pnic
= (LPNMLISTVIEW
) lParam
;
1195 if (pnic
->hdr
.hwndFrom
== m_ListView
->m_hWnd
)
1197 /* Check if this is a valid item
1198 * (technically, it can be also an unselect) */
1199 INT ItemIndex
= pnic
->iItem
;
1200 if (ItemIndex
== -1 ||
1201 ItemIndex
>= ListView_GetItemCount(pnic
->hdr
.hwndFrom
))
1206 /* Check if the focus has been moved to another item */
1207 if ((pnic
->uChanged
& LVIF_STATE
) &&
1208 (pnic
->uNewState
& LVIS_FOCUSED
) &&
1209 !(pnic
->uOldState
& LVIS_FOCUSED
))
1211 if (IsInstalledEnum(SelectedEnumType
))
1212 ShowInstalledAppInfo(ItemIndex
);
1213 if (IsAvailableEnum(SelectedEnumType
))
1214 CAvailableAppView::ShowAvailableAppInfo(ItemIndex
);
1216 /* Check if the item is checked */
1217 if ((pnic
->uNewState
& LVIS_STATEIMAGEMASK
) && !bUpdating
)
1219 BOOL checked
= m_ListView
->GetCheckState(pnic
->iItem
);
1221 - preventing decremention below zero as a safeguard for ReactOS
1222 In ReactOS this action is triggered whenever user changes *selection*, but should be only when *checkbox* state toggled
1223 Maybe LVIS_STATEIMAGEMASK is set incorrectly
1228 : ((nSelectedApps
> 0)
1232 /* Update item's selection status */
1233 m_ListView
->SetSelected(pnic
->iItem
, checked
);
1235 UpdateStatusBarText();
1241 case LVN_COLUMNCLICK
:
1243 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
) lParam
;
1245 m_ListView
->ColumnClick(pnmv
);
1251 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
1253 if (IsInstalledEnum(SelectedEnumType
))
1254 ShowInstalledAppInfo(-1);
1255 if (IsAvailableEnum(SelectedEnumType
))
1256 CAvailableAppView::ShowAvailableAppInfo(-1);
1263 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
1265 /* this won't do anything if the program is already installed */
1266 SendMessageW(hwnd
, WM_COMMAND
, ID_INSTALL
, 0);
1273 if (data
->hwndFrom
== m_ListView
->m_hWnd
&& ((LPNMLISTVIEW
) lParam
)->iItem
!= -1)
1275 ShowPopupMenu(m_ListView
->m_hWnd
, 0, ID_INSTALL
);
1281 OnLink((ENLINK
*) lParam
);
1284 case TTN_GETDISPINFO
:
1285 m_Toolbar
->OnGetDispInfo((LPTOOLTIPTEXT
) lParam
);
1292 OnSize(hwnd
, wParam
, lParam
);
1297 LPRECT pRect
= (LPRECT
) lParam
;
1299 if (pRect
->right
- pRect
->left
< 565)
1300 pRect
->right
= pRect
->left
+ 565;
1302 if (pRect
->bottom
- pRect
->top
< 300)
1303 pRect
->bottom
= pRect
->top
+ 300;
1308 case WM_SYSCOLORCHANGE
:
1310 /* Forward WM_SYSCOLORCHANGE to common controls */
1311 m_ListView
->SendMessageW(WM_SYSCOLORCHANGE
, 0, 0);
1312 m_TreeView
->SendMessageW(WM_SYSCOLORCHANGE
, 0, 0);
1313 m_Toolbar
->SendMessageW(WM_SYSCOLORCHANGE
, 0, 0);
1314 m_ListView
->SendMessageW(EM_SETBKGNDCOLOR
, 0, GetSysColor(COLOR_BTNFACE
));
1319 if (wParam
== SEARCH_TIMER_ID
)
1321 ::KillTimer(hwnd
, SEARCH_TIMER_ID
);
1323 UpdateApplicationsList(-1);
1331 virtual VOID
OnLink(ENLINK
*Link
)
1338 if (pLink
) HeapFree(GetProcessHeap(), 0, pLink
);
1340 pLink
= (LPWSTR
) HeapAlloc(GetProcessHeap(), 0,
1341 (max(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) -
1342 min(Link
->chrg
.cpMin
, Link
->chrg
.cpMax
) + 1) * sizeof(WCHAR
));
1345 /* TODO: Error message */
1349 m_RichEdit
->SendMessageW(EM_SETSEL
, Link
->chrg
.cpMin
, Link
->chrg
.cpMax
);
1350 m_RichEdit
->SendMessageW(EM_GETSELTEXT
, 0, (LPARAM
) pLink
);
1352 ShowPopupMenu(m_RichEdit
->m_hWnd
, IDR_LINKMENU
, -1);
1358 BOOL
IsSelectedNodeInstalled()
1360 HTREEITEM hSelectedItem
= m_TreeView
->GetSelection();
1363 tItem
.mask
= TVIF_PARAM
| TVIF_HANDLE
;
1364 tItem
.hItem
= hSelectedItem
;
1365 m_TreeView
->GetItem(&tItem
);
1366 switch (tItem
.lParam
)
1369 case IDS_APPLICATIONS
:
1377 VOID
OnCommand(WPARAM wParam
, LPARAM lParam
)
1379 WORD wCommand
= LOWORD(wParam
);
1381 if (lParam
== (LPARAM
) m_SearchBar
->m_hWnd
)
1383 ATL::CStringW szBuf
;
1385 switch (HIWORD(wParam
))
1389 ATL::CStringW szWndText
;
1391 szBuf
.LoadStringW(IDS_SEARCH_TEXT
);
1392 m_SearchBar
->GetWindowTextW(szWndText
);
1393 if (szBuf
== szWndText
)
1395 bSearchEnabled
= FALSE
;
1396 m_SearchBar
->SetWindowTextW(L
"");
1403 m_SearchBar
->GetWindowTextW(szBuf
);
1404 if (szBuf
.IsEmpty())
1406 szBuf
.LoadStringW(IDS_SEARCH_TEXT
);
1407 bSearchEnabled
= FALSE
;
1408 m_SearchBar
->SetWindowTextW(szBuf
.GetString());
1415 ATL::CStringW szWndText
;
1417 if (!bSearchEnabled
)
1419 bSearchEnabled
= TRUE
;
1423 szBuf
.LoadStringW(IDS_SEARCH_TEXT
);
1424 m_SearchBar
->GetWindowTextW(szWndText
);
1425 if (szBuf
== szWndText
)
1427 szSearchPattern
.Empty();
1431 szSearchPattern
= szWndText
;
1435 SystemParametersInfoW(SPI_GETMENUSHOWDELAY
, 0, &dwDelay
, 0);
1436 SetTimer(SEARCH_TIMER_ID
, dwDelay
);
1447 ShellExecuteW(m_hWnd
, L
"open", pLink
, NULL
, NULL
, SW_SHOWNOACTIVATE
);
1448 HeapFree(GetProcessHeap(), 0, pLink
);
1452 CopyTextToClipboard(pLink
);
1453 HeapFree(GetProcessHeap(), 0, pLink
);
1457 CreateSettingsDlg(m_hWnd
);
1461 PostMessageW(WM_CLOSE
, 0, 0);
1465 ::SetFocus(m_SearchBar
->m_hWnd
);
1469 if (IsAvailableEnum(SelectedEnumType
))
1471 if (nSelectedApps
> 0)
1473 CDownloadManager::DownloadListOfApplications(m_AvailableApps
.GetSelected());
1474 UpdateApplicationsList(-1);
1475 m_ListView
->SetSelected(-1, FALSE
);
1477 else if (CDownloadManager::DownloadApplication(m_ListView
->GetSelectedData()))
1479 UpdateApplicationsList(-1);
1486 if (UninstallApplication(-1, FALSE
))
1487 UpdateApplicationsList(-1);
1491 if (UninstallApplication(-1, TRUE
))
1492 UpdateApplicationsList(-1);
1496 RemoveAppFromRegistry(-1);
1500 UpdateApplicationsList(-1);
1504 CAvailableApps::ForceUpdateAppsDB();
1505 UpdateApplicationsList(-1);
1509 MessageBoxW(L
"Help not implemented yet", NULL
, MB_OK
);
1517 m_ListView
->CheckAll();
1522 VOID
FreeInstalledAppList()
1524 INT Count
= m_ListView
->GetItemCount() - 1;
1525 PINSTALLED_INFO Info
;
1529 Info
= (PINSTALLED_INFO
) ListViewGetlParam(Count
);
1532 RegCloseKey(Info
->hSubKey
);
1539 static BOOL
SearchPatternMatch(LPCWSTR szHaystack
, LPCWSTR szNeedle
)
1543 /* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
1544 return StrStrIW(szHaystack
, szNeedle
) != NULL
;
1547 static BOOL CALLBACK
s_EnumInstalledAppProc(INT ItemIndex
, ATL::CStringW
&m_szName
, PINSTALLED_INFO Info
)
1549 PINSTALLED_INFO ItemInfo
;
1550 ATL::CStringW szText
;
1553 if (!SearchPatternMatch(m_szName
.GetString(), szSearchPattern
))
1555 RegCloseKey(Info
->hSubKey
);
1559 ItemInfo
= new INSTALLED_INFO(*Info
);
1562 RegCloseKey(Info
->hSubKey
);
1566 Index
= ListViewAddItem(ItemIndex
, 0, m_szName
, (LPARAM
) ItemInfo
);
1568 /* Get version info */
1569 GetApplicationString(ItemInfo
->hSubKey
, L
"DisplayVersion", szText
);
1570 ListView_SetItemText(hListView
, Index
, 1, const_cast<LPWSTR
>(szText
.GetString()));
1573 GetApplicationString(ItemInfo
->hSubKey
, L
"Comments", szText
);
1574 ListView_SetItemText(hListView
, Index
, 2, const_cast<LPWSTR
>(szText
.GetString()));
1579 static BOOL CALLBACK
s_EnumAvailableAppProc(CAvailableApplicationInfo
* Info
, LPCWSTR szFolderPath
)
1584 HIMAGELIST hImageListView
= ListView_GetImageList(hListView
, LVSIL_SMALL
);
1586 if (!SearchPatternMatch(Info
->m_szName
.GetString(), szSearchPattern
) &&
1587 !SearchPatternMatch(Info
->m_szDesc
.GetString(), szSearchPattern
))
1592 /* Load icon from file */
1593 ATL::CStringW szIconPath
;
1594 szIconPath
.Format(L
"%lsicons\\%ls.ico", szFolderPath
, Info
->m_szName
.GetString());
1595 hIcon
= (HICON
) LoadImageW(NULL
,
1596 szIconPath
.GetString(),
1602 if (!hIcon
|| GetLastError() != ERROR_SUCCESS
)
1604 /* Load default icon */
1605 hIcon
= (HICON
) LoadIconW(hInst
, MAKEINTRESOURCEW(IDI_MAIN
));
1608 Index
= ImageList_AddIcon(hImageListView
, hIcon
);
1611 Index
= ListViewAddItem(Info
->m_Category
, Index
, Info
->m_szName
.GetString(), (LPARAM
) Info
);
1612 ListView_SetImageList(hListView
, hImageListView
, LVSIL_SMALL
);
1614 ListView_SetItemText(hListView
, Index
, 1, const_cast<LPWSTR
>(Info
->m_szVersion
.GetString()));
1615 ListView_SetItemText(hListView
, Index
, 2, const_cast<LPWSTR
>(Info
->m_szDesc
.GetString()));
1616 ListView_SetCheckState(hListView
, Index
, Info
->m_IsSelected
);
1621 VOID
UpdateStatusBarText()
1625 ATL::CStringW szBuffer
;
1627 szBuffer
.Format(IDS_APPS_COUNT
, m_ListView
->GetItemCount(), nSelectedApps
);
1628 m_StatusBar
->SetText(szBuffer
);
1632 VOID
UpdateApplicationsList(INT EnumType
)
1634 ATL::CStringW szBuffer1
, szBuffer2
;
1635 HIMAGELIST hImageListView
;
1636 BOOL bWasInInstalled
= IsInstalledEnum(SelectedEnumType
);
1639 m_ListView
->SetRedraw(FALSE
);
1643 EnumType
= SelectedEnumType
;
1646 //if previous one was INSTALLED purge the list
1647 //TODO: make the Installed category a separate class to avoid doing this
1648 if (bWasInInstalled
)
1650 FreeInstalledAppList();
1653 m_ListView
->DeleteAllItems();
1655 // Create new ImageList
1656 hImageListView
= ImageList_Create(LISTVIEW_ICON_SIZE
,
1658 GetSystemColorDepth() | ILC_MASK
,
1660 HIMAGELIST hImageListBuf
= m_ListView
->SetImageList(hImageListView
, LVSIL_SMALL
);
1663 ImageList_Destroy(hImageListBuf
);
1666 if (IsInstalledEnum(EnumType
))
1668 if (!bWasInInstalled
)
1670 m_ListView
->SetCheckboxesVisible(FALSE
);
1673 HICON hIcon
= (HICON
) LoadIconW(hInst
, MAKEINTRESOURCEW(IDI_MAIN
));
1674 ImageList_AddIcon(hImageListView
, hIcon
);
1677 // Enum installed applications and updates
1678 EnumInstalledApplications(EnumType
, TRUE
, s_EnumInstalledAppProc
);
1679 EnumInstalledApplications(EnumType
, FALSE
, s_EnumInstalledAppProc
);
1681 else if (IsAvailableEnum(EnumType
))
1683 if (bWasInInstalled
)
1685 m_ListView
->SetCheckboxesVisible(TRUE
);
1688 // Enum available applications
1689 m_AvailableApps
.Enum(EnumType
, s_EnumAvailableAppProc
);
1692 SelectedEnumType
= EnumType
;
1693 UpdateStatusBarText();
1696 // Set automatic column width for program names if the list is not empty
1697 if (m_ListView
->GetItemCount() > 0)
1699 ListView_SetColumnWidth(m_ListView
->GetWindow(), 0, LVSCW_AUTOSIZE
);
1703 m_ListView
->SetRedraw(TRUE
);
1707 static ATL::CWndClassInfo
& GetWndClassInfo()
1709 DWORD csStyle
= CS_VREDRAW
| CS_HREDRAW
;
1710 static ATL::CWndClassInfo wc
=
1719 LoadIconW(_AtlBaseModule
.GetModuleInstance(), MAKEINTRESOURCEW(IDI_MAIN
)),
1720 LoadCursorW(NULL
, IDC_ARROW
),
1721 (HBRUSH
) (COLOR_BTNFACE
+ 1),
1722 MAKEINTRESOURCEW(IDR_MAINMENU
),
1726 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
1733 ATL::CStringW szWindowName
;
1734 szWindowName
.LoadStringW(IDS_APPTITLE
);
1737 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Left
: CW_USEDEFAULT
),
1738 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Top
: CW_USEDEFAULT
),
1739 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Width
: 680),
1740 (SettingsInfo
.bSaveWndPos
? SettingsInfo
.Height
: 450)
1745 return CWindowImpl::Create(NULL
, r
, szWindowName
.GetString(), WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
, WS_EX_WINDOWEDGE
);
1748 CStatusBar
* GetStatusBar()
1753 CAppsListView
* GetListView()
1758 CRichEdit
* GetRichEdit()
1763 CAvailableApps
* GetAvailableApps()
1765 return &m_AvailableApps
;
1770 CMainWindow
* g_MainWindow
;
1772 HWND
CreateMainWindow()
1774 g_MainWindow
= new CMainWindow();
1775 return g_MainWindow
->Create();
1778 DWORD_PTR
ListViewGetlParam(INT item
)
1782 item
= g_MainWindow
->GetListView()->GetSelectionMark();
1784 return g_MainWindow
->GetListView()->GetItemData(item
);
1787 VOID
SetStatusBarText(LPCWSTR szText
)
1789 g_MainWindow
->GetStatusBar()->SetText(szText
);
1792 INT
ListViewAddItem(INT ItemIndex
, INT IconIndex
, LPWSTR lpName
, LPARAM lParam
)
1794 return g_MainWindow
->GetListView()->AddItem(ItemIndex
, IconIndex
, lpName
, lParam
);
1797 VOID
NewRichEditText(LPCWSTR szText
, DWORD flags
)
1799 g_MainWindow
->GetRichEdit()->SetText(szText
, flags
);
1802 VOID
InsertRichEditText(LPCWSTR szText
, DWORD flags
)
1804 g_MainWindow
->GetRichEdit()->InsertText(szText
, flags
);
1807 CAvailableApps
* GetAvailableApps()
1809 return g_MainWindow
->GetAvailableApps();
1812 // ATL version of functions above
1813 VOID
SetStatusBarText(const ATL::CStringW
& szText
)
1815 SetStatusBarText(szText
.GetString());
1818 INT
ListViewAddItem(INT ItemIndex
, INT IconIndex
, const ATL::CStringW
& Name
, LPARAM lParam
)
1820 return ListViewAddItem(ItemIndex
, IconIndex
, const_cast<LPWSTR
>(Name
.GetString()), lParam
);
1823 VOID
NewRichEditText(const ATL::CStringW
& szText
, DWORD flags
)
1825 NewRichEditText(szText
.GetString(), flags
);
1828 VOID
InsertRichEditText(const ATL::CStringW
& szText
, DWORD flags
)
1830 InsertRichEditText(szText
.GetString(), flags
);
1833 VOID
ShowMainWindow(INT nShowCmd
)
1838 hMainWnd
= CreateMainWindow();
1842 /* Maximize it if we must */
1843 ShowWindow(hMainWnd
, ((SettingsInfo
.bSaveWndPos
&& SettingsInfo
.Maximized
) ? SW_MAXIMIZE
: nShowCmd
));
1844 UpdateWindow(hMainWnd
);
1846 /* Load the menu hotkeys */
1847 KeyBrd
= LoadAcceleratorsW(NULL
, MAKEINTRESOURCEW(HOTKEYS
));
1850 while (GetMessageW(&Msg
, NULL
, 0, 0))
1852 if (!TranslateAcceleratorW(hMainWnd
, KeyBrd
, &Msg
))
1854 TranslateMessage(&Msg
);
1855 DispatchMessageW(&Msg
);