applpage.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. /*
  2. * ReactOS Task Manager
  3. *
  4. * applpage.c
  5. *
  6. * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
  7. * Copyright (C) 2008 Vladimir Pankratov
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <windows.h>
  26. #include <commctrl.h>
  27. #include "taskmgr.h"
  28. typedef struct
  29. {
  30. HWND hWnd;
  31. WCHAR wszTitle[256];
  32. HICON hIcon;
  33. BOOL bHung;
  34. } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM;
  35. HWND hApplicationPage; /* Application List Property Page */
  36. HWND hApplicationPageListCtrl; /* Application ListCtrl Window */
  37. HWND hApplicationPageEndTaskButton; /* Application End Task button */
  38. HWND hApplicationPageSwitchToButton; /* Application Switch To button */
  39. HWND hApplicationPageNewTaskButton; /* Application New Task button */
  40. static int nApplicationPageWidth;
  41. static int nApplicationPageHeight;
  42. static HANDLE hApplicationPageEvent = NULL; /* When this event becomes signaled then we refresh the app list */
  43. static BOOL bSortAscending = TRUE;
  44. static const WCHAR wszUser32[] = {'U','S','E','R','3','2','.','D','L','L',0};
  45. static void ApplicationPageUpdate(void)
  46. {
  47. /* Enable or disable the "End Task" & "Switch To" buttons */
  48. if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0))
  49. {
  50. EnableWindow(hApplicationPageEndTaskButton, TRUE);
  51. EnableWindow(hApplicationPageSwitchToButton, TRUE);
  52. }
  53. else
  54. {
  55. EnableWindow(hApplicationPageEndTaskButton, FALSE);
  56. EnableWindow(hApplicationPageSwitchToButton, FALSE);
  57. }
  58. /* If we are on the applications tab, then the windows menu will */
  59. /* be present on the menu bar so enable & disable the menu items */
  60. if (SendMessageW(hTabWnd, TCM_GETCURSEL, 0, 0) == 0)
  61. {
  62. HMENU hMenu;
  63. HMENU hWindowsMenu;
  64. UINT count;
  65. hMenu = GetMenu(hMainWnd);
  66. hWindowsMenu = GetSubMenu(hMenu, 3);
  67. count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
  68. /* Only one item selected */
  69. if (count == 1)
  70. {
  71. EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  72. EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  73. EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
  74. EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
  75. EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  76. EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
  77. }
  78. /* More than one item selected */
  79. else if (count > 1)
  80. {
  81. EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
  82. EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
  83. EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
  84. EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
  85. EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
  86. EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  87. }
  88. /* No items selected */
  89. else
  90. {
  91. EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  92. EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  93. EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  94. EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  95. EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  96. EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  97. }
  98. }
  99. }
  100. static void AddOrUpdateHwnd(HWND hWnd, WCHAR *wszTitle, HICON hIcon, BOOL bHung)
  101. {
  102. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  103. HIMAGELIST hImageListLarge;
  104. HIMAGELIST hImageListSmall;
  105. LV_ITEMW item;
  106. int i, count;
  107. BOOL bAlreadyInList = FALSE;
  108. BOOL bItemRemoved = FALSE;
  109. memset(&item, 0, sizeof(LV_ITEMW));
  110. /* Get the image lists */
  111. hImageListLarge = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_NORMAL, 0);
  112. hImageListSmall = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_SMALL, 0);
  113. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  114. /* Check to see if it's already in our list */
  115. for (i=0; i<count; i++)
  116. {
  117. memset(&item, 0, sizeof(LV_ITEMW));
  118. item.mask = LVIF_IMAGE|LVIF_PARAM;
  119. item.iItem = i;
  120. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  121. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  122. if (pAPLI->hWnd == hWnd)
  123. {
  124. bAlreadyInList = TRUE;
  125. break;
  126. }
  127. }
  128. /* If it is already in the list then update it if necessary */
  129. if (bAlreadyInList)
  130. {
  131. /* Check to see if anything needs updating */
  132. if ((pAPLI->hIcon != hIcon) ||
  133. (lstrcmpW(pAPLI->wszTitle, wszTitle) != 0) ||
  134. (pAPLI->bHung != bHung))
  135. {
  136. /* Update the structure */
  137. pAPLI->hIcon = hIcon;
  138. pAPLI->bHung = bHung;
  139. lstrcpyW(pAPLI->wszTitle, wszTitle);
  140. /* Update the image list */
  141. ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
  142. ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
  143. /* Update the list view */
  144. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  145. SendMessageW(hApplicationPageListCtrl, LVM_REDRAWITEMS, 0, count);
  146. /* UpdateWindow(hApplicationPageListCtrl); */
  147. InvalidateRect(hApplicationPageListCtrl, NULL, 0);
  148. }
  149. }
  150. /* It is not already in the list so add it */
  151. else
  152. {
  153. pAPLI = HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
  154. pAPLI->hWnd = hWnd;
  155. pAPLI->hIcon = hIcon;
  156. pAPLI->bHung = bHung;
  157. lstrcpyW(pAPLI->wszTitle, wszTitle);
  158. /* Add the item to the list */
  159. memset(&item, 0, sizeof(LV_ITEMW));
  160. item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
  161. ImageList_AddIcon(hImageListLarge, hIcon);
  162. item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
  163. item.pszText = LPSTR_TEXTCALLBACKW;
  164. item.iItem = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  165. item.lParam = (LPARAM)pAPLI;
  166. SendMessageW(hApplicationPageListCtrl, LVM_INSERTITEMW, 0, (LPARAM) &item);
  167. }
  168. /* Check to see if we need to remove any items from the list */
  169. for (i=SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0)-1; i>=0; i--)
  170. {
  171. memset(&item, 0, sizeof(LV_ITEMW));
  172. item.mask = LVIF_IMAGE|LVIF_PARAM;
  173. item.iItem = i;
  174. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  175. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  176. if (!IsWindow(pAPLI->hWnd)||
  177. (lstrlenW(pAPLI->wszTitle) <= 0) ||
  178. !IsWindowVisible(pAPLI->hWnd) ||
  179. (GetParent(pAPLI->hWnd) != NULL) ||
  180. (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
  181. (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
  182. {
  183. ImageList_Remove(hImageListLarge, item.iItem);
  184. ImageList_Remove(hImageListSmall, item.iItem);
  185. SendMessageW(hApplicationPageListCtrl, LVM_DELETEITEM, item.iItem, 0);
  186. HeapFree(GetProcessHeap(), 0, pAPLI);
  187. bItemRemoved = TRUE;
  188. }
  189. }
  190. /*
  191. * If an item was removed from the list then
  192. * we need to resync all the items with the
  193. * image list
  194. */
  195. if (bItemRemoved)
  196. {
  197. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  198. for (i=0; i<count; i++)
  199. {
  200. memset(&item, 0, sizeof(LV_ITEMW));
  201. item.mask = LVIF_IMAGE;
  202. item.iItem = i;
  203. item.iImage = i;
  204. SendMessageW(hApplicationPageListCtrl, LVM_SETITEMW, 0, (LPARAM) &item);
  205. }
  206. }
  207. ApplicationPageUpdate();
  208. }
  209. static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
  210. {
  211. HICON hIcon;
  212. WCHAR wszText[256];
  213. BOOL bLargeIcon = TaskManagerSettings.View_LargeIcons;
  214. BOOL bHung = FALSE;
  215. typedef int (__stdcall *IsHungAppWindowProc)(HWND);
  216. IsHungAppWindowProc IsHungAppWindow;
  217. /* Skip our window */
  218. if (hWnd == hMainWnd)
  219. return TRUE;
  220. /* Check and see if this is a top-level app window */
  221. if (!GetWindowTextW(hWnd, wszText, ARRAY_SIZE(wszText)) || !IsWindowVisible(hWnd) ||
  222. (GetParent(hWnd) != NULL) || (GetWindow(hWnd, GW_OWNER) != NULL) ||
  223. (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
  224. {
  225. return TRUE; /* Skip this window */
  226. }
  227. /* Get the icon for this window */
  228. hIcon = NULL;
  229. SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
  230. if (!hIcon)
  231. {
  232. hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM);
  233. if (!hIcon) hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON);
  234. if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)&hIcon);
  235. if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
  236. }
  237. if (!hIcon)
  238. hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
  239. bHung = FALSE;
  240. IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(wszUser32), "IsHungAppWindow");
  241. if (IsHungAppWindow)
  242. bHung = IsHungAppWindow(hWnd);
  243. AddOrUpdateHwnd(hWnd, wszText, hIcon, bHung);
  244. return TRUE;
  245. }
  246. static DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
  247. {
  248. /* Create the event */
  249. hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
  250. /* If we couldn't create the event then exit the thread */
  251. if (!hApplicationPageEvent)
  252. return 0;
  253. while (1)
  254. {
  255. DWORD dwWaitVal;
  256. /* Wait on the event */
  257. dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
  258. /* If the wait failed then the event object must have been */
  259. /* closed and the task manager is exiting so exit this thread */
  260. if (dwWaitVal == WAIT_FAILED)
  261. return 0;
  262. if (dwWaitVal == WAIT_OBJECT_0)
  263. {
  264. /* Reset our event */
  265. ResetEvent(hApplicationPageEvent);
  266. /*
  267. * FIXME:
  268. *
  269. * Should this be EnumDesktopWindows() instead?
  270. */
  271. EnumWindows(EnumWindowsProc, 0);
  272. }
  273. }
  274. }
  275. static void ApplicationPageShowContextMenu1(void)
  276. {
  277. HMENU hMenu;
  278. HMENU hSubMenu;
  279. POINT pt;
  280. GetCursorPos(&pt);
  281. hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
  282. hSubMenu = GetSubMenu(hMenu, 0);
  283. if (TaskManagerSettings.View_LargeIcons)
  284. CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
  285. else if (TaskManagerSettings.View_SmallIcons)
  286. CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
  287. else
  288. CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
  289. TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
  290. DestroyMenu(hMenu);
  291. }
  292. static void ApplicationPageShowContextMenu2(void)
  293. {
  294. HMENU hMenu;
  295. HMENU hSubMenu;
  296. UINT count;
  297. POINT pt;
  298. GetCursorPos(&pt);
  299. hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
  300. hSubMenu = GetSubMenu(hMenu, 0);
  301. count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
  302. if (count == 1)
  303. {
  304. EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  305. EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  306. EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
  307. EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
  308. EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  309. EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
  310. }
  311. else if (count > 1)
  312. {
  313. EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
  314. EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
  315. EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
  316. EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
  317. EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
  318. EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  319. }
  320. else
  321. {
  322. EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  323. EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  324. EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  325. EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  326. EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  327. EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  328. }
  329. SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
  330. TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
  331. DestroyMenu(hMenu);
  332. }
  333. static int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  334. {
  335. LPAPPLICATION_PAGE_LIST_ITEM Param1;
  336. LPAPPLICATION_PAGE_LIST_ITEM Param2;
  337. if (bSortAscending) {
  338. Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
  339. Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
  340. } else {
  341. Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
  342. Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
  343. }
  344. return lstrcmpW(Param1->wszTitle, Param2->wszTitle);
  345. }
  346. static void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
  347. {
  348. LPNMHDR pnmh;
  349. LV_DISPINFOW* pnmdi;
  350. LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
  351. WCHAR wszNotResponding[255];
  352. WCHAR wszRunning[255];
  353. LoadStringW(hInst, IDS_APPLICATION_NOT_RESPONDING, wszNotResponding, ARRAY_SIZE(wszNotResponding));
  354. LoadStringW(hInst, IDS_APPLICATION_RUNNING, wszRunning, ARRAY_SIZE(wszRunning));
  355. pnmh = (LPNMHDR) lParam;
  356. pnmdi = (LV_DISPINFOW*) lParam;
  357. if (pnmh->hwndFrom == hApplicationPageListCtrl) {
  358. switch (pnmh->code) {
  359. case LVN_ITEMCHANGED:
  360. ApplicationPageUpdate();
  361. break;
  362. case LVN_GETDISPINFOW:
  363. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
  364. /* Update the item text */
  365. if (pnmdi->item.iSubItem == 0)
  366. {
  367. lstrcpynW(pnmdi->item.pszText, pAPLI->wszTitle, pnmdi->item.cchTextMax);
  368. }
  369. /* Update the item status */
  370. else if (pnmdi->item.iSubItem == 1)
  371. {
  372. if (pAPLI->bHung)
  373. lstrcpynW(pnmdi->item.pszText, wszNotResponding, pnmdi->item.cchTextMax);
  374. else
  375. lstrcpynW(pnmdi->item.pszText, wszRunning, pnmdi->item.cchTextMax);
  376. }
  377. break;
  378. case NM_RCLICK:
  379. if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
  380. {
  381. ApplicationPageShowContextMenu1();
  382. }
  383. else
  384. {
  385. ApplicationPageShowContextMenu2();
  386. }
  387. break;
  388. case NM_DBLCLK:
  389. ApplicationPage_OnSwitchTo();
  390. break;
  391. }
  392. }
  393. else if (pnmh->hwndFrom == (HWND)SendMessageW(hApplicationPageListCtrl, LVM_GETHEADER, 0, 0))
  394. {
  395. switch (pnmh->code)
  396. {
  397. case NM_RCLICK:
  398. if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
  399. {
  400. ApplicationPageShowContextMenu1();
  401. }
  402. else
  403. {
  404. ApplicationPageShowContextMenu2();
  405. }
  406. break;
  407. case HDN_ITEMCLICKW:
  408. SendMessageW(hApplicationPageListCtrl, LVM_SORTITEMS, 0, (LPARAM) ApplicationPageCompareFunc);
  409. bSortAscending = !bSortAscending;
  410. break;
  411. }
  412. }
  413. }
  414. void RefreshApplicationPage(void)
  415. {
  416. /* Signal the event so that our refresh thread */
  417. /* will wake up and refresh the application page */
  418. SetEvent(hApplicationPageEvent);
  419. }
  420. static void UpdateApplicationListControlViewSetting(void)
  421. {
  422. DWORD dwStyle = GetWindowLongW(hApplicationPageListCtrl, GWL_STYLE);
  423. dwStyle &= ~LVS_REPORT;
  424. dwStyle &= ~LVS_ICON;
  425. dwStyle &= ~LVS_LIST;
  426. dwStyle &= ~LVS_SMALLICON;
  427. if (TaskManagerSettings.View_LargeIcons)
  428. dwStyle |= LVS_ICON;
  429. else if (TaskManagerSettings.View_SmallIcons)
  430. dwStyle |= LVS_SMALLICON;
  431. else
  432. dwStyle |= LVS_REPORT;
  433. SetWindowLongW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
  434. RefreshApplicationPage();
  435. }
  436. void ApplicationPage_OnViewLargeIcons(void)
  437. {
  438. HMENU hMenu;
  439. HMENU hViewMenu;
  440. hMenu = GetMenu(hMainWnd);
  441. hViewMenu = GetSubMenu(hMenu, 2);
  442. TaskManagerSettings.View_LargeIcons = TRUE;
  443. TaskManagerSettings.View_SmallIcons = FALSE;
  444. TaskManagerSettings.View_Details = FALSE;
  445. CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
  446. UpdateApplicationListControlViewSetting();
  447. }
  448. void ApplicationPage_OnViewSmallIcons(void)
  449. {
  450. HMENU hMenu;
  451. HMENU hViewMenu;
  452. hMenu = GetMenu(hMainWnd);
  453. hViewMenu = GetSubMenu(hMenu, 2);
  454. TaskManagerSettings.View_LargeIcons = FALSE;
  455. TaskManagerSettings.View_SmallIcons = TRUE;
  456. TaskManagerSettings.View_Details = FALSE;
  457. CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
  458. UpdateApplicationListControlViewSetting();
  459. }
  460. void ApplicationPage_OnViewDetails(void)
  461. {
  462. HMENU hMenu;
  463. HMENU hViewMenu;
  464. hMenu = GetMenu(hMainWnd);
  465. hViewMenu = GetSubMenu(hMenu, 2);
  466. TaskManagerSettings.View_LargeIcons = FALSE;
  467. TaskManagerSettings.View_SmallIcons = FALSE;
  468. TaskManagerSettings.View_Details = TRUE;
  469. CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
  470. UpdateApplicationListControlViewSetting();
  471. }
  472. void ApplicationPage_OnWindowsTileHorizontally(void)
  473. {
  474. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  475. LV_ITEMW item;
  476. int i, count;
  477. HWND* hWndArray;
  478. int nWndCount;
  479. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  480. hWndArray = HeapAlloc(GetProcessHeap(), 0,
  481. sizeof(HWND) * count);
  482. nWndCount = 0;
  483. for (i=0; i<count; i++) {
  484. memset(&item, 0, sizeof(LV_ITEMW));
  485. item.mask = LVIF_STATE|LVIF_PARAM;
  486. item.iItem = i;
  487. item.stateMask = (UINT)-1;
  488. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  489. if (item.state & LVIS_SELECTED) {
  490. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  491. if (pAPLI) {
  492. hWndArray[nWndCount] = pAPLI->hWnd;
  493. nWndCount++;
  494. }
  495. }
  496. }
  497. TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
  498. HeapFree(GetProcessHeap(), 0, hWndArray);
  499. }
  500. void ApplicationPage_OnWindowsTileVertically(void)
  501. {
  502. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  503. LV_ITEMW item;
  504. int i, count;
  505. HWND* hWndArray;
  506. int nWndCount;
  507. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  508. hWndArray = HeapAlloc(GetProcessHeap(), 0,
  509. sizeof(HWND) * count);
  510. nWndCount = 0;
  511. for (i=0; i<count; i++) {
  512. memset(&item, 0, sizeof(LV_ITEMW));
  513. item.mask = LVIF_STATE|LVIF_PARAM;
  514. item.iItem = i;
  515. item.stateMask = (UINT)-1;
  516. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  517. if (item.state & LVIS_SELECTED) {
  518. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  519. if (pAPLI) {
  520. hWndArray[nWndCount] = pAPLI->hWnd;
  521. nWndCount++;
  522. }
  523. }
  524. }
  525. TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
  526. HeapFree(GetProcessHeap(), 0, hWndArray);
  527. }
  528. void ApplicationPage_OnWindowsMinimize(void)
  529. {
  530. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  531. LV_ITEMW item;
  532. int i, count;
  533. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  534. for (i=0; i<count; i++) {
  535. memset(&item, 0, sizeof(LV_ITEMW));
  536. item.mask = LVIF_STATE|LVIF_PARAM;
  537. item.iItem = i;
  538. item.stateMask = (UINT)-1;
  539. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  540. if (item.state & LVIS_SELECTED) {
  541. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  542. if (pAPLI) {
  543. ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
  544. }
  545. }
  546. }
  547. }
  548. void ApplicationPage_OnWindowsMaximize(void)
  549. {
  550. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  551. LV_ITEMW item;
  552. int i, count;
  553. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  554. for (i=0; i<count; i++) {
  555. memset(&item, 0, sizeof(LV_ITEMW));
  556. item.mask = LVIF_STATE|LVIF_PARAM;
  557. item.iItem = i;
  558. item.stateMask = (UINT)-1;
  559. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  560. if (item.state & LVIS_SELECTED) {
  561. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  562. if (pAPLI) {
  563. ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
  564. }
  565. }
  566. }
  567. }
  568. void ApplicationPage_OnWindowsCascade(void)
  569. {
  570. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  571. LV_ITEMW item;
  572. int i, count;
  573. HWND* hWndArray;
  574. int nWndCount;
  575. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  576. hWndArray = HeapAlloc(GetProcessHeap(), 0,
  577. sizeof(HWND) * count);
  578. nWndCount = 0;
  579. for (i=0; i<count; i++) {
  580. memset(&item, 0, sizeof(LV_ITEMW));
  581. item.mask = LVIF_STATE|LVIF_PARAM;
  582. item.iItem = i;
  583. item.stateMask = (UINT)-1;
  584. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  585. if (item.state & LVIS_SELECTED) {
  586. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  587. if (pAPLI) {
  588. hWndArray[nWndCount] = pAPLI->hWnd;
  589. nWndCount++;
  590. }
  591. }
  592. }
  593. CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
  594. HeapFree(GetProcessHeap(), 0, hWndArray);
  595. }
  596. void ApplicationPage_OnWindowsBringToFront(void)
  597. {
  598. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  599. LV_ITEMW item;
  600. int i, count;
  601. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  602. for (i=0; i<count; i++) {
  603. memset(&item, 0, sizeof(LV_ITEMW));
  604. item.mask = LVIF_STATE|LVIF_PARAM;
  605. item.iItem = i;
  606. item.stateMask = (UINT)-1;
  607. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  608. if (item.state & LVIS_SELECTED) {
  609. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  610. break;
  611. }
  612. }
  613. if (pAPLI) {
  614. if (IsIconic(pAPLI->hWnd))
  615. ShowWindow(pAPLI->hWnd, SW_RESTORE);
  616. BringWindowToTop(pAPLI->hWnd);
  617. }
  618. }
  619. void ApplicationPage_OnSwitchTo(void)
  620. {
  621. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  622. LV_ITEMW item;
  623. int i, count;
  624. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  625. for (i=0; i<count; i++) {
  626. memset(&item, 0, sizeof(LV_ITEMW));
  627. item.mask = LVIF_STATE|LVIF_PARAM;
  628. item.iItem = i;
  629. item.stateMask = (UINT)-1;
  630. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  631. if (item.state & LVIS_SELECTED) {
  632. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  633. break;
  634. }
  635. }
  636. if (pAPLI) {
  637. typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
  638. PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
  639. HMODULE hUser32 = GetModuleHandleW(wszUser32);
  640. SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
  641. if (SwitchToThisWindow) {
  642. SwitchToThisWindow(pAPLI->hWnd, TRUE);
  643. } else {
  644. if (IsIconic(pAPLI->hWnd))
  645. ShowWindow(pAPLI->hWnd, SW_RESTORE);
  646. BringWindowToTop(pAPLI->hWnd);
  647. SetForegroundWindow(pAPLI->hWnd);
  648. }
  649. if (TaskManagerSettings.MinimizeOnUse)
  650. ShowWindow(hMainWnd, SW_MINIMIZE);
  651. }
  652. }
  653. void ApplicationPage_OnEndTask(void)
  654. {
  655. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  656. LV_ITEMW item;
  657. int i, count;
  658. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  659. for (i=0; i<count; i++) {
  660. memset(&item, 0, sizeof(LV_ITEMW));
  661. item.mask = LVIF_STATE|LVIF_PARAM;
  662. item.iItem = i;
  663. item.stateMask = (UINT)-1;
  664. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  665. if (item.state & LVIS_SELECTED) {
  666. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  667. if (pAPLI) {
  668. PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
  669. }
  670. }
  671. }
  672. }
  673. void ApplicationPage_OnGotoProcess(void)
  674. {
  675. LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
  676. LV_ITEMW item;
  677. int i, count;
  678. /* NMHDR nmhdr; */
  679. count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
  680. for (i=0; i<count; i++) {
  681. memset(&item, 0, sizeof(LV_ITEMW));
  682. item.mask = LVIF_STATE|LVIF_PARAM;
  683. item.iItem = i;
  684. item.stateMask = (UINT)-1;
  685. SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
  686. if (item.state & LVIS_SELECTED) {
  687. pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
  688. break;
  689. }
  690. }
  691. if (pAPLI) {
  692. DWORD dwProcessId;
  693. GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
  694. /*
  695. * Switch to the process tab
  696. */
  697. SendMessageW(hTabWnd, TCM_SETCURFOCUS, 1, 0);
  698. /*
  699. * FIXME: Select the process item in the list
  700. */
  701. }
  702. }
  703. INT_PTR CALLBACK
  704. ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  705. {
  706. RECT rc;
  707. int nXDifference;
  708. int nYDifference;
  709. int cx, cy;
  710. LVCOLUMNW column;
  711. WCHAR wszTask[255];
  712. WCHAR wszStatus[255];
  713. LoadStringW(hInst, IDS_APPLICATION_TASK, wszTask, ARRAY_SIZE(wszTask));
  714. LoadStringW(hInst, IDS_APPLICATION_STATUS, wszStatus, ARRAY_SIZE(wszStatus));
  715. switch (message) {
  716. case WM_INITDIALOG:
  717. /* Save the width and height */
  718. GetClientRect(hDlg, &rc);
  719. nApplicationPageWidth = rc.right;
  720. nApplicationPageHeight = rc.bottom;
  721. /* Update window position */
  722. SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
  723. /* Get handles to the controls */
  724. hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
  725. hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
  726. hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
  727. hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
  728. /* Initialize the application page's controls */
  729. column.mask = LVCF_TEXT|LVCF_WIDTH;
  730. column.pszText = wszTask;
  731. column.cx = 250;
  732. /* Add the "Task" column */
  733. SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM) &column);
  734. column.mask = LVCF_TEXT|LVCF_WIDTH;
  735. column.pszText = wszStatus;
  736. column.cx = 95;
  737. /* Add the "Status" column */
  738. SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
  739. SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_SMALL,
  740. (LPARAM) ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1));
  741. SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_NORMAL,
  742. (LPARAM) ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1));
  743. UpdateApplicationListControlViewSetting();
  744. /* Start our refresh thread */
  745. CloseHandle( CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL));
  746. return TRUE;
  747. case WM_DESTROY:
  748. /* Close the event handle, this will make the */
  749. /* refresh thread exit when the wait fails */
  750. CloseHandle(hApplicationPageEvent);
  751. break;
  752. case WM_COMMAND:
  753. /* Handle the button clicks */
  754. switch (LOWORD(wParam))
  755. {
  756. case IDC_ENDTASK:
  757. ApplicationPage_OnEndTask();
  758. break;
  759. case IDC_SWITCHTO:
  760. ApplicationPage_OnSwitchTo();
  761. break;
  762. case IDC_NEWTASK:
  763. SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
  764. break;
  765. }
  766. break;
  767. case WM_SIZE:
  768. if (wParam == SIZE_MINIMIZED)
  769. return 0;
  770. cx = LOWORD(lParam);
  771. cy = HIWORD(lParam);
  772. nXDifference = cx - nApplicationPageWidth;
  773. nYDifference = cy - nApplicationPageHeight;
  774. nApplicationPageWidth = cx;
  775. nApplicationPageHeight = cy;
  776. /* Reposition the application page's controls */
  777. GetWindowRect(hApplicationPageListCtrl, &rc);
  778. cx = (rc.right - rc.left) + nXDifference;
  779. cy = (rc.bottom - rc.top) + nYDifference;
  780. SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
  781. InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
  782. GetClientRect(hApplicationPageEndTaskButton, &rc);
  783. MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
  784. cx = rc.left + nXDifference;
  785. cy = rc.top + nYDifference;
  786. SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
  787. InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
  788. GetClientRect(hApplicationPageSwitchToButton, &rc);
  789. MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
  790. cx = rc.left + nXDifference;
  791. cy = rc.top + nYDifference;
  792. SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
  793. InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
  794. GetClientRect(hApplicationPageNewTaskButton, &rc);
  795. MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
  796. cx = rc.left + nXDifference;
  797. cy = rc.top + nYDifference;
  798. SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
  799. InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
  800. break;
  801. case WM_NOTIFY:
  802. ApplicationPageOnNotify(wParam, lParam);
  803. break;
  804. }
  805. return 0;
  806. }