2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/rapps/winmain.c
5 * PURPOSE: Main program
6 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
13 #define SEARCH_TIMER_ID 'SR'
17 HIMAGELIST hImageTreeView
= NULL
;
18 INT SelectedEnumType
= ENUM_ALL_COMPONENTS
;
19 SETTINGS_INFO SettingsInfo
;
21 PCWSTR (WINAPI
*pStrStrIW
)(PCWSTR
, PCWSTR
);
23 WCHAR szSearchPattern
[MAX_STR_LEN
] = L
"";
24 BOOL SearchEnabled
= TRUE
;
27 SearchPatternMatch(PCWSTR szHaystack
, PCWSTR szNeedle
)
31 /* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
32 return pStrStrIW(szHaystack
, szNeedle
) != NULL
;
36 FillDefaultSettings(PSETTINGS_INFO pSettingsInfo
)
38 pSettingsInfo
->bSaveWndPos
= TRUE
;
39 pSettingsInfo
->bUpdateAtStart
= FALSE
;
40 pSettingsInfo
->bLogEnabled
= TRUE
;
41 StringCbCopyW(pSettingsInfo
->szDownloadDir
,
42 sizeof(pSettingsInfo
->szDownloadDir
),
44 pSettingsInfo
->bDelInstaller
= FALSE
;
46 pSettingsInfo
->Maximized
= FALSE
;
47 pSettingsInfo
->Left
= 0;
48 pSettingsInfo
->Top
= 0;
49 pSettingsInfo
->Right
= 680;
50 pSettingsInfo
->Bottom
= 450;
59 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\ReactOS\\rapps", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
61 dwSize
= sizeof(SETTINGS_INFO
);
62 if (RegQueryValueExW(hKey
, L
"Settings", NULL
, NULL
, (LPBYTE
)&SettingsInfo
, &dwSize
) == ERROR_SUCCESS
)
75 SaveSettings(HWND hwnd
)
80 if (SettingsInfo
.bSaveWndPos
)
82 wp
.length
= sizeof(WINDOWPLACEMENT
);
83 GetWindowPlacement(hwnd
, &wp
);
85 SettingsInfo
.Left
= wp
.rcNormalPosition
.left
;
86 SettingsInfo
.Top
= wp
.rcNormalPosition
.top
;
87 SettingsInfo
.Right
= wp
.rcNormalPosition
.right
;
88 SettingsInfo
.Bottom
= wp
.rcNormalPosition
.bottom
;
89 SettingsInfo
.Maximized
= (IsZoomed(hwnd
) || (wp
.flags
& WPF_RESTORETOMAXIMIZED
));
92 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Software\\ReactOS\\rapps", 0, NULL
,
93 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
95 RegSetValueExW(hKey
, L
"Settings", 0, REG_BINARY
, (LPBYTE
)&SettingsInfo
, sizeof(SETTINGS_INFO
));
101 FreeInstalledAppList(VOID
)
103 INT Count
= ListView_GetItemCount(hListView
) - 1;
104 PINSTALLED_INFO Info
;
108 Info
= ListViewGetlParam(Count
);
111 RegCloseKey(Info
->hSubKey
);
112 HeapFree(GetProcessHeap(), 0, Info
);
120 EnumInstalledAppProc(INT ItemIndex
, LPWSTR lpName
, INSTALLED_INFO Info
)
122 PINSTALLED_INFO ItemInfo
;
123 WCHAR szText
[MAX_PATH
];
126 if (!SearchPatternMatch(lpName
, szSearchPattern
))
129 ItemInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO
));
130 if (!ItemInfo
) return FALSE
;
134 Index
= ListViewAddItem(ItemIndex
, 0, lpName
, (LPARAM
)ItemInfo
);
136 /* Get version info */
137 GetApplicationString(ItemInfo
->hSubKey
, L
"DisplayVersion", szText
);
138 ListView_SetItemText(hListView
, Index
, 1, szText
);
140 GetApplicationString(ItemInfo
->hSubKey
, L
"Comments", szText
);
141 ListView_SetItemText(hListView
, Index
, 2, szText
);
147 FreeAvailableAppList(VOID
)
149 INT Count
= ListView_GetItemCount(hListView
) - 1;
154 Info
= ListViewGetlParam(Count
);
156 HeapFree(GetProcessHeap(), 0, Info
);
163 EnumAvailableAppProc(APPLICATION_INFO Info
)
165 PAPPLICATION_INFO ItemInfo
;
168 if (!SearchPatternMatch(Info
.szName
, szSearchPattern
) &&
169 !SearchPatternMatch(Info
.szDesc
, szSearchPattern
))
174 /* Only add a ListView entry if...
175 - no RegName was supplied (so we cannot determine whether the application is installed or not) or
176 - a RegName was supplied and the application is not installed
178 if (!*Info
.szRegName
|| (!IsInstalledApplication(Info
.szRegName
, FALSE
) && !IsInstalledApplication(Info
.szRegName
, TRUE
)))
180 ItemInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_INFO
));
181 if (!ItemInfo
) return FALSE
;
185 Index
= ListViewAddItem(Info
.Category
, 0, Info
.szName
, (LPARAM
)ItemInfo
);
186 ListView_SetItemText(hListView
, Index
, 1, Info
.szVersion
);
187 ListView_SetItemText(hListView
, Index
, 2, Info
.szDesc
);
194 UpdateApplicationsList(INT EnumType
)
196 WCHAR szBuffer1
[MAX_STR_LEN
], szBuffer2
[MAX_STR_LEN
];
198 HIMAGELIST hImageListView
;
200 (VOID
) ListView_DeleteAllItems(hListView
);
202 /* Create image list */
203 hImageListView
= ImageList_Create(LISTVIEW_ICON_SIZE
,
205 GetSystemColorDepth() | ILC_MASK
,
208 hIcon
= LoadImage(hInst
,
209 MAKEINTRESOURCE(IDI_MAIN
),
213 LR_CREATEDIBSECTION
);
215 ImageList_AddIcon(hImageListView
, hIcon
);
218 if (EnumType
== -1) EnumType
= SelectedEnumType
;
220 if (IS_INSTALLED_ENUM(SelectedEnumType
))
221 FreeInstalledAppList();
222 else if (IS_AVAILABLE_ENUM(SelectedEnumType
))
223 FreeAvailableAppList();
225 if (IS_INSTALLED_ENUM(EnumType
))
227 /* Enum installed applications and updates */
228 EnumInstalledApplications(EnumType
, TRUE
, EnumInstalledAppProc
);
229 EnumInstalledApplications(EnumType
, FALSE
, EnumInstalledAppProc
);
231 else if (IS_AVAILABLE_ENUM(EnumType
))
233 /* Enum availabled applications */
234 EnumAvailableApplications(EnumType
, EnumAvailableAppProc
);
237 /* Set image list for ListView */
238 hImageListView
= ListView_SetImageList(hListView
, hImageListView
, LVSIL_SMALL
);
240 /* Destroy old image list */
242 ImageList_Destroy(hImageListView
);
244 SelectedEnumType
= EnumType
;
246 LoadStringW(hInst
, IDS_APPS_COUNT
, szBuffer2
, sizeof(szBuffer2
) / sizeof(WCHAR
));
247 StringCbPrintfW(szBuffer1
, sizeof(szBuffer1
),
249 ListView_GetItemCount(hListView
));
250 SetStatusBarText(szBuffer1
);
256 InitApplicationsList(VOID
)
258 WCHAR szText
[MAX_STR_LEN
];
260 /* Add columns to ListView */
261 LoadStringW(hInst
, IDS_APP_NAME
, szText
, sizeof(szText
) / sizeof(WCHAR
));
262 ListViewAddColumn(0, szText
, 200, LVCFMT_LEFT
);
264 LoadStringW(hInst
, IDS_APP_INST_VERSION
, szText
, sizeof(szText
) / sizeof(WCHAR
));
265 ListViewAddColumn(1, szText
, 90, LVCFMT_RIGHT
);
267 LoadStringW(hInst
, IDS_APP_DESCRIPTION
, szText
, sizeof(szText
) / sizeof(WCHAR
));
268 ListViewAddColumn(3, szText
, 250, LVCFMT_LEFT
);
270 UpdateApplicationsList(ENUM_ALL_COMPONENTS
);
274 AddCategory(HTREEITEM hRootItem
, UINT TextIndex
, UINT IconIndex
)
276 WCHAR szText
[MAX_STR_LEN
];
280 hIcon
= LoadImage(hInst
,
281 MAKEINTRESOURCE(IconIndex
),
285 LR_CREATEDIBSECTION
);
287 Index
= ImageList_AddIcon(hImageTreeView
, hIcon
);
290 LoadStringW(hInst
, TextIndex
, szText
, sizeof(szText
) / sizeof(TCHAR
));
292 return TreeViewAddItem(hRootItem
, szText
, Index
, Index
, TextIndex
);
296 InitCategoriesList(VOID
)
298 HTREEITEM hRootItem1
, hRootItem2
;
300 /* Create image list */
301 hImageTreeView
= ImageList_Create(TREEVIEW_ICON_SIZE
,
303 GetSystemColorDepth() | ILC_MASK
,
306 hRootItem1
= AddCategory(TVI_ROOT
, IDS_INSTALLED
, IDI_CATEGORY
);
307 AddCategory(hRootItem1
, IDS_APPLICATIONS
, IDI_APPS
);
308 AddCategory(hRootItem1
, IDS_UPDATES
, IDI_APPUPD
);
310 hRootItem2
= AddCategory(TVI_ROOT
, IDS_AVAILABLEFORINST
, IDI_CATEGORY
);
311 AddCategory(hRootItem2
, IDS_CAT_AUDIO
, IDI_CAT_AUDIO
);
312 AddCategory(hRootItem2
, IDS_CAT_VIDEO
, IDI_CAT_VIDEO
);
313 AddCategory(hRootItem2
, IDS_CAT_GRAPHICS
, IDI_CAT_GRAPHICS
);
314 AddCategory(hRootItem2
, IDS_CAT_GAMES
, IDI_CAT_GAMES
);
315 AddCategory(hRootItem2
, IDS_CAT_INTERNET
, IDI_CAT_INTERNET
);
316 AddCategory(hRootItem2
, IDS_CAT_OFFICE
, IDI_CAT_OFFICE
);
317 AddCategory(hRootItem2
, IDS_CAT_DEVEL
, IDI_CAT_DEVEL
);
318 AddCategory(hRootItem2
, IDS_CAT_EDU
, IDI_CAT_EDU
);
319 AddCategory(hRootItem2
, IDS_CAT_ENGINEER
, IDI_CAT_ENGINEER
);
320 AddCategory(hRootItem2
, IDS_CAT_FINANCE
, IDI_CAT_FINANCE
);
321 AddCategory(hRootItem2
, IDS_CAT_SCIENCE
, IDI_CAT_SCIENCE
);
322 AddCategory(hRootItem2
, IDS_CAT_TOOLS
, IDI_CAT_TOOLS
);
323 AddCategory(hRootItem2
, IDS_CAT_DRIVERS
, IDI_CAT_DRIVERS
);
324 AddCategory(hRootItem2
, IDS_CAT_LIBS
, IDI_CAT_LIBS
);
325 AddCategory(hRootItem2
, IDS_CAT_OTHER
, IDI_CAT_OTHER
);
327 (VOID
) TreeView_SetImageList(hTreeView
, hImageTreeView
, TVSIL_NORMAL
);
329 (VOID
) TreeView_Expand(hTreeView
, hRootItem2
, TVE_EXPAND
);
330 (VOID
) TreeView_Expand(hTreeView
, hRootItem1
, TVE_EXPAND
);
332 (VOID
) TreeView_SelectItem(hTreeView
, hRootItem1
);
336 InitControls(HWND hwnd
)
338 if (SettingsInfo
.bSaveWndPos
)
340 MoveWindow(hwnd
, SettingsInfo
.Left
, SettingsInfo
.Top
,
341 SettingsInfo
.Right
- SettingsInfo
.Left
,
342 SettingsInfo
.Bottom
- SettingsInfo
.Top
, TRUE
);
344 if (SettingsInfo
.Maximized
) ShowWindow(hwnd
, SW_MAXIMIZE
);
347 if (CreateStatusBar(hwnd
) &&
348 CreateToolBar(hwnd
) &&
349 CreateListView(hwnd
) &&
350 CreateTreeView(hwnd
) &&
351 CreateRichEdit(hwnd
) &&
352 CreateVSplitBar(hwnd
) &&
353 CreateHSplitBar(hwnd
))
355 WCHAR szBuffer1
[MAX_STR_LEN
], szBuffer2
[MAX_STR_LEN
];
357 InitApplicationsList();
359 InitCategoriesList();
361 LoadStringW(hInst
, IDS_APPS_COUNT
, szBuffer2
, sizeof(szBuffer2
) / sizeof(WCHAR
));
362 StringCbPrintfW(szBuffer1
, sizeof(szBuffer1
),
364 ListView_GetItemCount(hListView
));
365 SetStatusBarText(szBuffer1
);
373 SearchTimerProc(HWND hwnd
, UINT uMsg
, UINT_PTR idEvent
, DWORD dwTime
)
375 KillTimer(hwnd
, SEARCH_TIMER_ID
);
376 UpdateApplicationsList(-1);
380 MainWndOnCommand(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
382 WORD wCommand
= LOWORD(wParam
);
384 if (lParam
== (LPARAM
)hSearchBar
)
386 WCHAR szBuf
[MAX_STR_LEN
];
388 switch (HIWORD(wParam
))
392 WCHAR szWndText
[MAX_STR_LEN
];
394 LoadStringW(hInst
, IDS_SEARCH_TEXT
, szBuf
, sizeof(szBuf
) / sizeof(WCHAR
));
395 GetWindowTextW(hSearchBar
, szWndText
, MAX_STR_LEN
);
396 if (wcscmp(szBuf
, szWndText
) == 0)
398 SearchEnabled
= FALSE
;
399 SetWindowTextW(hSearchBar
, L
"");
406 GetWindowTextW(hSearchBar
, szBuf
, MAX_STR_LEN
);
407 if (wcslen(szBuf
) < 1)
409 LoadStringW(hInst
, IDS_SEARCH_TEXT
, szBuf
, sizeof(szBuf
) / sizeof(WCHAR
));
410 SearchEnabled
= FALSE
;
411 SetWindowTextW(hSearchBar
, szBuf
);
418 WCHAR szWndText
[MAX_STR_LEN
];
422 SearchEnabled
= TRUE
;
426 LoadStringW(hInst
, IDS_SEARCH_TEXT
, szBuf
, sizeof(szBuf
) / sizeof(WCHAR
));
427 GetWindowTextW(hSearchBar
, szWndText
, MAX_STR_LEN
);
428 if (wcscmp(szBuf
, szWndText
) != 0)
430 StringCbCopy(szSearchPattern
, sizeof(szSearchPattern
),
435 szSearchPattern
[0] = UNICODE_NULL
;
438 SetTimer(hwnd
, SEARCH_TIMER_ID
, 250, SearchTimerProc
);
449 ShellExecuteW(hwnd
, L
"open", pLink
, NULL
, NULL
, SW_SHOWNOACTIVATE
);
450 HeapFree(GetProcessHeap(), 0, pLink
);
454 CopyTextToClipboard(pLink
);
455 HeapFree(GetProcessHeap(), 0, pLink
);
459 CreateSettingsDlg(hwnd
);
463 PostMessageW(hwnd
, WM_CLOSE
, 0, 0);
467 if (DownloadApplication(-1))
468 /* TODO: Implement install dialog
469 * if (InstallApplication(-1))
471 UpdateApplicationsList(-1);
475 if (UninstallApplication(-1, FALSE
))
476 UpdateApplicationsList(-1);
480 if (UninstallApplication(-1, TRUE
))
481 UpdateApplicationsList(-1);
485 RemoveAppFromRegistry(-1);
489 UpdateApplicationsList(-1);
494 UpdateApplicationsList(-1);
498 MessageBoxW(hwnd
, L
"Help not implemented yet", NULL
, MB_OK
);
508 MainWndOnSize(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
510 HDWP hdwp
= BeginDeferWindowPos(5);
511 INT SearchBarWidth
= GetWindowWidth(hSearchBar
);
512 INT RichPos
= GetWindowHeight(hRichEdit
);
513 INT NewPos
= HIWORD(lParam
) - (RichPos
+ SPLIT_WIDTH
+ GetWindowHeight(hStatusBar
));
516 /* Size status bar */
517 SendMessage(hStatusBar
, WM_SIZE
, 0, 0);
520 SendMessage(hToolBar
, TB_AUTOSIZE
, 0, 0);
523 MoveWindow(hSearchBar
, LOWORD(lParam
) - SearchBarWidth
- 4, 5, SearchBarWidth
, 22, TRUE
);
526 * HIWORD(lParam) - Height of main window
527 * LOWORD(lParam) - Width of main window
530 /* Size vertical splitter bar */
534 (VSplitterPos
= GetWindowWidth(hTreeView
)),
535 GetWindowHeight(hToolBar
),
537 HIWORD(lParam
) - GetWindowHeight(hToolBar
) - GetWindowHeight(hStatusBar
),
538 SWP_NOZORDER
|SWP_NOACTIVATE
);
545 GetWindowHeight(hToolBar
),
547 HIWORD(lParam
) - GetWindowHeight(hToolBar
) - GetWindowHeight(hStatusBar
),
548 SWP_NOZORDER
|SWP_NOACTIVATE
);
550 while (NewPos
< SPLIT_WIDTH
+ GetWindowHeight(hToolBar
))
553 NewPos
= HIWORD(lParam
) - (RichPos
+
554 SPLIT_WIDTH
+ GetWindowHeight(hStatusBar
));
556 SetHSplitterPos(NewPos
);
562 VSplitterPos
+ SPLIT_WIDTH
,
563 GetWindowHeight(hToolBar
),
564 LOWORD(lParam
) - (VSplitterPos
+ SPLIT_WIDTH
),
565 GetHSplitterPos() - GetWindowHeight(hToolBar
),
566 SWP_NOZORDER
|SWP_NOACTIVATE
);
572 VSplitterPos
+ SPLIT_WIDTH
,
573 GetHSplitterPos() + SPLIT_WIDTH
,
574 LOWORD(lParam
) - (VSplitterPos
+ SPLIT_WIDTH
),
576 SWP_NOZORDER
|SWP_NOACTIVATE
);
578 /* Size horizontal splitter bar */
582 VSplitterPos
+ SPLIT_WIDTH
,
584 LOWORD(lParam
) - (VSplitterPos
+ SPLIT_WIDTH
),
586 SWP_NOZORDER
|SWP_NOACTIVATE
);
588 EndDeferWindowPos(hdwp
);
591 BOOL
IsSelectedNodeInstalled(void)
593 HTREEITEM hSelectedItem
= TreeView_GetSelection(hTreeView
);
596 tItem
.mask
= TVIF_PARAM
| TVIF_HANDLE
;
597 tItem
.hItem
= hSelectedItem
;
598 TreeView_GetItem(hTreeView
, &tItem
);
599 switch (tItem
.lParam
)
602 case IDS_APPLICATIONS
:
611 MainWindowProc(HWND hwnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
616 if (!InitControls(hwnd
))
617 PostMessage(hwnd
, WM_CLOSE
, 0, 0);
622 MainWndOnCommand(hwnd
, wParam
, lParam
);
627 LPNMHDR data
= (LPNMHDR
)lParam
;
633 if (data
->hwndFrom
== hTreeView
)
635 switch (((LPNMTREEVIEW
)lParam
)->itemNew
.lParam
)
638 UpdateApplicationsList(ENUM_ALL_COMPONENTS
);
641 case IDS_APPLICATIONS
:
642 UpdateApplicationsList(ENUM_APPLICATIONS
);
646 UpdateApplicationsList(ENUM_UPDATES
);
649 case IDS_AVAILABLEFORINST
:
650 UpdateApplicationsList(ENUM_ALL_AVAILABLE
);
654 UpdateApplicationsList(ENUM_CAT_AUDIO
);
658 UpdateApplicationsList(ENUM_CAT_DEVEL
);
661 case IDS_CAT_DRIVERS
:
662 UpdateApplicationsList(ENUM_CAT_DRIVERS
);
666 UpdateApplicationsList(ENUM_CAT_EDU
);
669 case IDS_CAT_ENGINEER
:
670 UpdateApplicationsList(ENUM_CAT_ENGINEER
);
673 case IDS_CAT_FINANCE
:
674 UpdateApplicationsList(ENUM_CAT_FINANCE
);
678 UpdateApplicationsList(ENUM_CAT_GAMES
);
681 case IDS_CAT_GRAPHICS
:
682 UpdateApplicationsList(ENUM_CAT_GRAPHICS
);
685 case IDS_CAT_INTERNET
:
686 UpdateApplicationsList(ENUM_CAT_INTERNET
);
690 UpdateApplicationsList(ENUM_CAT_LIBS
);
694 UpdateApplicationsList(ENUM_CAT_OFFICE
);
698 UpdateApplicationsList(ENUM_CAT_OTHER
);
701 case IDS_CAT_SCIENCE
:
702 UpdateApplicationsList(ENUM_CAT_SCIENCE
);
706 UpdateApplicationsList(ENUM_CAT_TOOLS
);
710 UpdateApplicationsList(ENUM_CAT_VIDEO
);
715 /* Disable/enable items based on treeview selection */
716 if (IsSelectedNodeInstalled())
718 EnableMenuItem(GetMenu(hwnd
), ID_REGREMOVE
, MF_ENABLED
);
719 EnableMenuItem(GetMenu(hwnd
), ID_INSTALL
, MF_GRAYED
);
720 EnableMenuItem(GetMenu(hwnd
), ID_UNINSTALL
, MF_ENABLED
);
721 EnableMenuItem(GetMenu(hwnd
), ID_MODIFY
, MF_ENABLED
);
723 EnableMenuItem(GetMenu(hListView
), ID_REGREMOVE
, MF_ENABLED
);
724 EnableMenuItem(GetMenu(hListView
), ID_INSTALL
, MF_GRAYED
);
725 EnableMenuItem(GetMenu(hListView
), ID_UNINSTALL
, MF_ENABLED
);
726 EnableMenuItem(GetMenu(hListView
), ID_MODIFY
, MF_ENABLED
);
728 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_REGREMOVE
, TRUE
);
729 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_INSTALL
, FALSE
);
730 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_UNINSTALL
, TRUE
);
731 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_MODIFY
, TRUE
);
735 EnableMenuItem(GetMenu(hwnd
), ID_REGREMOVE
, MF_GRAYED
);
736 EnableMenuItem(GetMenu(hwnd
), ID_INSTALL
, MF_ENABLED
);
737 EnableMenuItem(GetMenu(hwnd
), ID_UNINSTALL
, MF_GRAYED
);
738 EnableMenuItem(GetMenu(hwnd
), ID_MODIFY
, MF_GRAYED
);
740 EnableMenuItem(GetMenu(hListView
), ID_REGREMOVE
, MF_GRAYED
);
741 EnableMenuItem(GetMenu(hListView
), ID_INSTALL
, MF_ENABLED
);
742 EnableMenuItem(GetMenu(hListView
), ID_UNINSTALL
, MF_GRAYED
);
743 EnableMenuItem(GetMenu(hListView
), ID_MODIFY
, MF_GRAYED
);
745 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_REGREMOVE
, FALSE
);
746 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_INSTALL
, TRUE
);
747 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_UNINSTALL
, FALSE
);
748 SendMessage(hToolBar
, TB_ENABLEBUTTON
, ID_MODIFY
, FALSE
);
753 case LVN_ITEMCHANGED
:
755 LPNMLISTVIEW pnic
= (LPNMLISTVIEW
) lParam
;
757 if (pnic
->hdr
.hwndFrom
== hListView
)
759 /* Check if this is a valid item
760 * (technically, it can be also an unselect) */
761 INT ItemIndex
= pnic
->iItem
;
762 if (ItemIndex
== -1 ||
763 ItemIndex
>= ListView_GetItemCount(pnic
->hdr
.hwndFrom
))
768 /* Check if the focus has been moved to another item */
769 if ((pnic
->uChanged
& LVIF_STATE
) &&
770 (pnic
->uNewState
& LVIS_FOCUSED
) &&
771 !(pnic
->uOldState
& LVIS_FOCUSED
))
773 if (IS_INSTALLED_ENUM(SelectedEnumType
))
774 ShowInstalledAppInfo(ItemIndex
);
775 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
776 ShowAvailableAppInfo(ItemIndex
);
782 case LVN_COLUMNCLICK
:
784 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
) lParam
;
786 (VOID
) ListView_SortItems(hListView
, ListViewCompareFunc
, pnmv
->iSubItem
);
787 bAscending
= !bAscending
;
793 if (data
->hwndFrom
== hListView
&& ((LPNMLISTVIEW
)lParam
)->iItem
!= -1)
795 if (IS_INSTALLED_ENUM(SelectedEnumType
))
796 ShowInstalledAppInfo(-1);
797 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
798 ShowAvailableAppInfo(-1);
805 if (data
->hwndFrom
== hListView
&& ((LPNMLISTVIEW
)lParam
)->iItem
!= -1)
807 SendMessage(hwnd
, WM_COMMAND
, ID_INSTALL
, 0); //Won't do anything if the program is already installed
814 if (data
->hwndFrom
== hListView
&& ((LPNMLISTVIEW
)lParam
)->iItem
!= -1)
816 ShowPopupMenu(hListView
, 0, ID_INSTALL
);
822 RichEditOnLink(hwnd
, (ENLINK
*)lParam
);
825 case TTN_GETDISPINFO
:
826 ToolBarOnGetDispInfo((LPTOOLTIPTEXT
)lParam
);
837 if ((GetClientWindowHeight(hMainWnd
) - GetWindowHeight(hStatusBar
) - SPLIT_WIDTH
) < GetHSplitterPos())
839 INT NewSplitPos
= GetClientWindowHeight(hwnd
) - 100 - GetWindowHeight(hStatusBar
) - SPLIT_WIDTH
;
840 if (NewSplitPos
> GetWindowHeight(hToolBar
) + SPLIT_WIDTH
)
841 SetHSplitterPos(NewSplitPos
);
844 MainWndOnSize(hwnd
, wParam
, lParam
);
850 int RichEditHeight
= GetWindowHeight(hRichEdit
);
851 LPRECT pRect
= (LPRECT
)lParam
;
853 while (RichEditHeight
<= 100)
855 if (GetHSplitterPos() - 1 < GetWindowHeight(hToolBar
) + GetWindowHeight(hListView
) + SPLIT_WIDTH
)
857 SetHSplitterPos(GetHSplitterPos() - 1);
861 if (pRect
->right
-pRect
->left
< 565)
862 pRect
->right
= pRect
->left
+ 565;
864 if (pRect
->bottom
-pRect
->top
< 300)
865 pRect
->bottom
= pRect
->top
+ 300;
869 case WM_SYSCOLORCHANGE
:
871 /* Forward WM_SYSCOLORCHANGE to common controls */
872 SendMessage(hListView
, WM_SYSCOLORCHANGE
, 0, 0);
873 SendMessage(hTreeView
, WM_SYSCOLORCHANGE
, 0, 0);
874 SendMessage(hToolBar
, WM_SYSCOLORCHANGE
, 0, 0);
875 SendMessageW(hRichEdit
, EM_SETBKGNDCOLOR
, 0, GetSysColor(COLOR_BTNFACE
));
881 ShowWindow(hwnd
, SW_HIDE
);
886 if (IS_AVAILABLE_ENUM(SelectedEnumType
))
887 FreeAvailableAppList();
888 if (IS_INSTALLED_ENUM(SelectedEnumType
))
889 FreeInstalledAppList();
890 if (hImageTreeView
) ImageList_Destroy(hImageTreeView
);
898 return DefWindowProc(hwnd
, Msg
, wParam
, lParam
);
902 wWinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPWSTR lpCmdLine
, int nShowCmd
)
904 WNDCLASSEXW WndClass
= {0};
905 WCHAR szWindowClass
[] = L
"ROSAPPMGR";
906 WCHAR szWindowName
[MAX_STR_LEN
];
907 HANDLE hMutex
= NULL
;
910 /* FIXME: CORE-7786 requires this to be loaded at runtime because we
911 * would get comctl32's version otherwise */
912 pStrStrIW
= (PVOID
)GetProcAddress(GetModuleHandle(L
"shlwapi"), "StrStrIW");
914 switch (GetUserDefaultUILanguage())
916 case MAKELANGID(LANG_HEBREW
, SUBLANG_DEFAULT
):
917 SetProcessDefaultLayout(LAYOUT_RTL
);
926 hMutex
= CreateMutexW(NULL
, FALSE
, szWindowClass
);
927 if ((!hMutex
) || (GetLastError() == ERROR_ALREADY_EXISTS
))
929 /* If already started, it is found its window */
930 HWND hWindow
= FindWindowW(szWindowClass
, NULL
);
932 /* Activate window */
933 ShowWindow(hWindow
, SW_SHOWNORMAL
);
934 SetForegroundWindow(hWindow
);
940 FillDefaultSettings(&SettingsInfo
);
945 InitCommonControls();
947 /* Create the window */
948 WndClass
.cbSize
= sizeof(WNDCLASSEXW
);
949 WndClass
.lpszClassName
= szWindowClass
;
950 WndClass
.lpfnWndProc
= MainWindowProc
;
951 WndClass
.hInstance
= hInstance
;
952 WndClass
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_MAIN
));
953 WndClass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
954 WndClass
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
955 WndClass
.lpszMenuName
= MAKEINTRESOURCEW(IDR_MAINMENU
);
957 if (RegisterClassExW(&WndClass
) == (ATOM
)0) goto Exit
;
959 LoadStringW(hInst
, IDS_APPTITLE
, szWindowName
, sizeof(szWindowName
) / sizeof(WCHAR
));
961 hMainWnd
= CreateWindowExW(WS_EX_WINDOWEDGE
,
964 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
,
974 if (!hMainWnd
) goto Exit
;
977 ShowWindow(hMainWnd
, nShowCmd
);
978 UpdateWindow(hMainWnd
);
980 if (SettingsInfo
.bUpdateAtStart
)
984 while (GetMessage(&Msg
, NULL
, 0, 0))
986 TranslateMessage(&Msg
);
987 DispatchMessage(&Msg
);
991 if (hMutex
) CloseHandle(hMutex
);