Release 2.3.
[wine.git] / programs / taskmgr / applpage.c
blobe2874b59434786a2dd9819180b280be97e79947e
1 /*
2 * ReactOS Task Manager
4 * applpage.c
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 * Copyright (C) 2008 Vladimir Pankratov
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.
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.
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
24 #include <stdio.h>
25 #include <stdlib.h>
27 #include <windows.h>
28 #include <commctrl.h>
30 #include "wine/unicode.h"
31 #include "taskmgr.h"
33 typedef struct
35 HWND hWnd;
36 WCHAR wszTitle[256];
37 HICON hIcon;
38 BOOL bHung;
39 } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM;
41 HWND hApplicationPage; /* Application List Property Page */
42 HWND hApplicationPageListCtrl; /* Application ListCtrl Window */
43 HWND hApplicationPageEndTaskButton; /* Application End Task button */
44 HWND hApplicationPageSwitchToButton; /* Application Switch To button */
45 HWND hApplicationPageNewTaskButton; /* Application New Task button */
46 static int nApplicationPageWidth;
47 static int nApplicationPageHeight;
48 static HANDLE hApplicationPageEvent = NULL; /* When this event becomes signaled then we refresh the app list */
49 static BOOL bSortAscending = TRUE;
51 static const WCHAR wszUser32[] = {'U','S','E','R','3','2','.','D','L','L',0};
53 static void ApplicationPageUpdate(void)
55 /* Enable or disable the "End Task" & "Switch To" buttons */
56 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0))
58 EnableWindow(hApplicationPageEndTaskButton, TRUE);
59 EnableWindow(hApplicationPageSwitchToButton, TRUE);
61 else
63 EnableWindow(hApplicationPageEndTaskButton, FALSE);
64 EnableWindow(hApplicationPageSwitchToButton, FALSE);
67 /* If we are on the applications tab, then the windows menu will */
68 /* be present on the menu bar so enable & disable the menu items */
69 if (SendMessageW(hTabWnd, TCM_GETCURSEL, 0, 0) == 0)
71 HMENU hMenu;
72 HMENU hWindowsMenu;
73 UINT count;
75 hMenu = GetMenu(hMainWnd);
76 hWindowsMenu = GetSubMenu(hMenu, 3);
77 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
79 /* Only one item selected */
80 if (count == 1)
82 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
83 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
84 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
85 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
86 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
87 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
89 /* More than one item selected */
90 else if (count > 1)
92 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
93 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
94 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
95 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
96 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
97 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
99 /* No items selected */
100 else
102 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
103 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
104 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
105 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
106 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
107 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
112 static void AddOrUpdateHwnd(HWND hWnd, WCHAR *wszTitle, HICON hIcon, BOOL bHung)
114 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
115 HIMAGELIST hImageListLarge;
116 HIMAGELIST hImageListSmall;
117 LV_ITEMW item;
118 int i, count;
119 BOOL bAlreadyInList = FALSE;
120 BOOL bItemRemoved = FALSE;
122 memset(&item, 0, sizeof(LV_ITEMW));
124 /* Get the image lists */
125 hImageListLarge = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_NORMAL, 0);
126 hImageListSmall = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_SMALL, 0);
128 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
129 /* Check to see if it's already in our list */
130 for (i=0; i<count; i++)
132 memset(&item, 0, sizeof(LV_ITEMW));
133 item.mask = LVIF_IMAGE|LVIF_PARAM;
134 item.iItem = i;
135 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
137 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
138 if (pAPLI->hWnd == hWnd)
140 bAlreadyInList = TRUE;
141 break;
145 /* If it is already in the list then update it if necessary */
146 if (bAlreadyInList)
148 /* Check to see if anything needs updating */
149 if ((pAPLI->hIcon != hIcon) ||
150 (strcmpW(pAPLI->wszTitle, wszTitle) != 0) ||
151 (pAPLI->bHung != bHung))
153 /* Update the structure */
154 pAPLI->hIcon = hIcon;
155 pAPLI->bHung = bHung;
156 strcpyW(pAPLI->wszTitle, wszTitle);
158 /* Update the image list */
159 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
160 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
162 /* Update the list view */
163 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
164 SendMessageW(hApplicationPageListCtrl, LVM_REDRAWITEMS, 0, count);
165 /* UpdateWindow(hApplicationPageListCtrl); */
166 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
169 /* It is not already in the list so add it */
170 else
172 pAPLI = HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
174 pAPLI->hWnd = hWnd;
175 pAPLI->hIcon = hIcon;
176 pAPLI->bHung = bHung;
177 strcpyW(pAPLI->wszTitle, wszTitle);
179 /* Add the item to the list */
180 memset(&item, 0, sizeof(LV_ITEMW));
181 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
182 ImageList_AddIcon(hImageListLarge, hIcon);
183 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
184 item.pszText = LPSTR_TEXTCALLBACKW;
185 item.iItem = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
186 item.lParam = (LPARAM)pAPLI;
187 SendMessageW(hApplicationPageListCtrl, LVM_INSERTITEMW, 0, (LPARAM) &item);
191 /* Check to see if we need to remove any items from the list */
192 for (i=SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0)-1; i>=0; i--)
194 memset(&item, 0, sizeof(LV_ITEMW));
195 item.mask = LVIF_IMAGE|LVIF_PARAM;
196 item.iItem = i;
197 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
199 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
200 if (!IsWindow(pAPLI->hWnd)||
201 (strlenW(pAPLI->wszTitle) <= 0) ||
202 !IsWindowVisible(pAPLI->hWnd) ||
203 (GetParent(pAPLI->hWnd) != NULL) ||
204 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
205 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
207 ImageList_Remove(hImageListLarge, item.iItem);
208 ImageList_Remove(hImageListSmall, item.iItem);
210 SendMessageW(hApplicationPageListCtrl, LVM_DELETEITEM, item.iItem, 0);
211 HeapFree(GetProcessHeap(), 0, pAPLI);
212 bItemRemoved = TRUE;
217 * If an item was removed from the list then
218 * we need to resync all the items with the
219 * image list
221 if (bItemRemoved)
223 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
224 for (i=0; i<count; i++)
226 memset(&item, 0, sizeof(LV_ITEMW));
227 item.mask = LVIF_IMAGE;
228 item.iItem = i;
229 item.iImage = i;
230 SendMessageW(hApplicationPageListCtrl, LVM_SETITEMW, 0, (LPARAM) &item);
234 ApplicationPageUpdate();
237 static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
239 HICON hIcon;
240 WCHAR wszText[256];
241 BOOL bLargeIcon = TaskManagerSettings.View_LargeIcons;
242 BOOL bHung = FALSE;
243 typedef int (__stdcall *IsHungAppWindowProc)(HWND);
244 IsHungAppWindowProc IsHungAppWindow;
247 /* Skip our window */
248 if (hWnd == hMainWnd)
249 return TRUE;
251 /* Check and see if this is a top-level app window */
252 if (!GetWindowTextW(hWnd, wszText, sizeof(wszText)/sizeof(WCHAR)) ||
253 !IsWindowVisible(hWnd) ||
254 (GetParent(hWnd) != NULL) ||
255 (GetWindow(hWnd, GW_OWNER) != NULL) ||
256 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
258 return TRUE; /* Skip this window */
261 /* Get the icon for this window */
262 hIcon = NULL;
263 SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
265 if (!hIcon)
267 hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM);
268 if (!hIcon) hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON);
269 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)&hIcon);
270 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
273 if (!hIcon)
274 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
276 bHung = FALSE;
278 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(wszUser32), "IsHungAppWindow");
280 if (IsHungAppWindow)
281 bHung = IsHungAppWindow(hWnd);
283 AddOrUpdateHwnd(hWnd, wszText, hIcon, bHung);
285 return TRUE;
288 static DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
290 /* Create the event */
291 hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
293 /* If we couldn't create the event then exit the thread */
294 if (!hApplicationPageEvent)
295 return 0;
297 while (1)
299 DWORD dwWaitVal;
301 /* Wait on the event */
302 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
304 /* If the wait failed then the event object must have been */
305 /* closed and the task manager is exiting so exit this thread */
306 if (dwWaitVal == WAIT_FAILED)
307 return 0;
309 if (dwWaitVal == WAIT_OBJECT_0)
311 /* Reset our event */
312 ResetEvent(hApplicationPageEvent);
315 * FIXME:
317 * Should this be EnumDesktopWindows() instead?
319 EnumWindows(EnumWindowsProc, 0);
324 static void ApplicationPageShowContextMenu1(void)
326 HMENU hMenu;
327 HMENU hSubMenu;
328 POINT pt;
330 GetCursorPos(&pt);
332 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
333 hSubMenu = GetSubMenu(hMenu, 0);
335 if (TaskManagerSettings.View_LargeIcons)
336 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
337 else if (TaskManagerSettings.View_SmallIcons)
338 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
339 else
340 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
342 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
344 DestroyMenu(hMenu);
347 static void ApplicationPageShowContextMenu2(void)
349 HMENU hMenu;
350 HMENU hSubMenu;
351 UINT count;
352 POINT pt;
354 GetCursorPos(&pt);
356 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
357 hSubMenu = GetSubMenu(hMenu, 0);
359 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
360 if (count == 1)
362 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
363 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
364 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
365 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
366 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
367 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
369 else if (count > 1)
371 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
372 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
373 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
374 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
375 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
376 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
378 else
380 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
381 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
382 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
383 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
384 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
385 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
388 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
390 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
392 DestroyMenu(hMenu);
395 static int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
397 LPAPPLICATION_PAGE_LIST_ITEM Param1;
398 LPAPPLICATION_PAGE_LIST_ITEM Param2;
400 if (bSortAscending) {
401 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
402 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
403 } else {
404 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
405 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
407 return strcmpW(Param1->wszTitle, Param2->wszTitle);
410 static void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
412 LPNMHDR pnmh;
413 LV_DISPINFOW* pnmdi;
414 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
415 WCHAR wszNotResponding[255];
416 WCHAR wszRunning[255];
418 LoadStringW(hInst, IDS_APPLICATION_NOT_RESPONDING, wszNotResponding, sizeof(wszNotResponding)/sizeof(WCHAR));
419 LoadStringW(hInst, IDS_APPLICATION_RUNNING, wszRunning, sizeof(wszRunning)/sizeof(WCHAR));
421 pnmh = (LPNMHDR) lParam;
422 pnmdi = (LV_DISPINFOW*) lParam;
424 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
425 switch (pnmh->code) {
426 case LVN_ITEMCHANGED:
427 ApplicationPageUpdate();
428 break;
430 case LVN_GETDISPINFOW:
431 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
433 /* Update the item text */
434 if (pnmdi->item.iSubItem == 0)
436 lstrcpynW(pnmdi->item.pszText, pAPLI->wszTitle, pnmdi->item.cchTextMax);
439 /* Update the item status */
440 else if (pnmdi->item.iSubItem == 1)
442 if (pAPLI->bHung)
443 lstrcpynW(pnmdi->item.pszText, wszNotResponding, pnmdi->item.cchTextMax);
444 else
445 lstrcpynW(pnmdi->item.pszText, wszRunning, pnmdi->item.cchTextMax);
448 break;
450 case NM_RCLICK:
452 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
454 ApplicationPageShowContextMenu1();
456 else
458 ApplicationPageShowContextMenu2();
461 break;
463 case NM_DBLCLK:
465 ApplicationPage_OnSwitchTo();
467 break;
470 else if (pnmh->hwndFrom == (HWND)SendMessageW(hApplicationPageListCtrl, LVM_GETHEADER, 0, 0))
472 switch (pnmh->code)
474 case NM_RCLICK:
476 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
478 ApplicationPageShowContextMenu1();
480 else
482 ApplicationPageShowContextMenu2();
485 break;
487 case HDN_ITEMCLICKW:
489 SendMessageW(hApplicationPageListCtrl, LVM_SORTITEMS, 0, (LPARAM) ApplicationPageCompareFunc);
490 bSortAscending = !bSortAscending;
492 break;
498 void RefreshApplicationPage(void)
500 /* Signal the event so that our refresh thread */
501 /* will wake up and refresh the application page */
502 SetEvent(hApplicationPageEvent);
505 static void UpdateApplicationListControlViewSetting(void)
507 DWORD dwStyle = GetWindowLongW(hApplicationPageListCtrl, GWL_STYLE);
509 dwStyle &= ~LVS_REPORT;
510 dwStyle &= ~LVS_ICON;
511 dwStyle &= ~LVS_LIST;
512 dwStyle &= ~LVS_SMALLICON;
514 if (TaskManagerSettings.View_LargeIcons)
515 dwStyle |= LVS_ICON;
516 else if (TaskManagerSettings.View_SmallIcons)
517 dwStyle |= LVS_SMALLICON;
518 else
519 dwStyle |= LVS_REPORT;
521 SetWindowLongW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
523 RefreshApplicationPage();
526 void ApplicationPage_OnViewLargeIcons(void)
528 HMENU hMenu;
529 HMENU hViewMenu;
531 hMenu = GetMenu(hMainWnd);
532 hViewMenu = GetSubMenu(hMenu, 2);
534 TaskManagerSettings.View_LargeIcons = TRUE;
535 TaskManagerSettings.View_SmallIcons = FALSE;
536 TaskManagerSettings.View_Details = FALSE;
537 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
539 UpdateApplicationListControlViewSetting();
542 void ApplicationPage_OnViewSmallIcons(void)
544 HMENU hMenu;
545 HMENU hViewMenu;
547 hMenu = GetMenu(hMainWnd);
548 hViewMenu = GetSubMenu(hMenu, 2);
550 TaskManagerSettings.View_LargeIcons = FALSE;
551 TaskManagerSettings.View_SmallIcons = TRUE;
552 TaskManagerSettings.View_Details = FALSE;
553 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
555 UpdateApplicationListControlViewSetting();
558 void ApplicationPage_OnViewDetails(void)
560 HMENU hMenu;
561 HMENU hViewMenu;
563 hMenu = GetMenu(hMainWnd);
564 hViewMenu = GetSubMenu(hMenu, 2);
566 TaskManagerSettings.View_LargeIcons = FALSE;
567 TaskManagerSettings.View_SmallIcons = FALSE;
568 TaskManagerSettings.View_Details = TRUE;
569 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
571 UpdateApplicationListControlViewSetting();
574 void ApplicationPage_OnWindowsTileHorizontally(void)
576 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
577 LV_ITEMW item;
578 int i, count;
579 HWND* hWndArray;
580 int nWndCount;
582 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
583 hWndArray = HeapAlloc(GetProcessHeap(), 0,
584 sizeof(HWND) * count);
585 nWndCount = 0;
587 for (i=0; i<count; i++) {
588 memset(&item, 0, sizeof(LV_ITEMW));
589 item.mask = LVIF_STATE|LVIF_PARAM;
590 item.iItem = i;
591 item.stateMask = (UINT)-1;
592 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
594 if (item.state & LVIS_SELECTED) {
595 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
597 if (pAPLI) {
598 hWndArray[nWndCount] = pAPLI->hWnd;
599 nWndCount++;
603 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
604 HeapFree(GetProcessHeap(), 0, hWndArray);
607 void ApplicationPage_OnWindowsTileVertically(void)
609 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
610 LV_ITEMW item;
611 int i, count;
612 HWND* hWndArray;
613 int nWndCount;
615 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
616 hWndArray = HeapAlloc(GetProcessHeap(), 0,
617 sizeof(HWND) * count);
618 nWndCount = 0;
620 for (i=0; i<count; i++) {
621 memset(&item, 0, sizeof(LV_ITEMW));
622 item.mask = LVIF_STATE|LVIF_PARAM;
623 item.iItem = i;
624 item.stateMask = (UINT)-1;
625 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
627 if (item.state & LVIS_SELECTED) {
628 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
629 if (pAPLI) {
630 hWndArray[nWndCount] = pAPLI->hWnd;
631 nWndCount++;
636 TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
637 HeapFree(GetProcessHeap(), 0, hWndArray);
640 void ApplicationPage_OnWindowsMinimize(void)
642 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
643 LV_ITEMW item;
644 int i, count;
646 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
647 for (i=0; i<count; i++) {
648 memset(&item, 0, sizeof(LV_ITEMW));
649 item.mask = LVIF_STATE|LVIF_PARAM;
650 item.iItem = i;
651 item.stateMask = (UINT)-1;
652 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
653 if (item.state & LVIS_SELECTED) {
654 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
655 if (pAPLI) {
656 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
662 void ApplicationPage_OnWindowsMaximize(void)
664 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
665 LV_ITEMW item;
666 int i, count;
668 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
669 for (i=0; i<count; i++) {
670 memset(&item, 0, sizeof(LV_ITEMW));
671 item.mask = LVIF_STATE|LVIF_PARAM;
672 item.iItem = i;
673 item.stateMask = (UINT)-1;
674 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
675 if (item.state & LVIS_SELECTED) {
676 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
677 if (pAPLI) {
678 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
684 void ApplicationPage_OnWindowsCascade(void)
686 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
687 LV_ITEMW item;
688 int i, count;
689 HWND* hWndArray;
690 int nWndCount;
692 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
693 hWndArray = HeapAlloc(GetProcessHeap(), 0,
694 sizeof(HWND) * count);
695 nWndCount = 0;
697 for (i=0; i<count; i++) {
698 memset(&item, 0, sizeof(LV_ITEMW));
699 item.mask = LVIF_STATE|LVIF_PARAM;
700 item.iItem = i;
701 item.stateMask = (UINT)-1;
702 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
703 if (item.state & LVIS_SELECTED) {
704 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
705 if (pAPLI) {
706 hWndArray[nWndCount] = pAPLI->hWnd;
707 nWndCount++;
711 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
712 HeapFree(GetProcessHeap(), 0, hWndArray);
715 void ApplicationPage_OnWindowsBringToFront(void)
717 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
718 LV_ITEMW item;
719 int i, count;
721 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
722 for (i=0; i<count; i++) {
723 memset(&item, 0, sizeof(LV_ITEMW));
724 item.mask = LVIF_STATE|LVIF_PARAM;
725 item.iItem = i;
726 item.stateMask = (UINT)-1;
727 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
728 if (item.state & LVIS_SELECTED) {
729 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
730 break;
733 if (pAPLI) {
734 if (IsIconic(pAPLI->hWnd))
735 ShowWindow(pAPLI->hWnd, SW_RESTORE);
736 BringWindowToTop(pAPLI->hWnd);
740 void ApplicationPage_OnSwitchTo(void)
742 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
743 LV_ITEMW item;
744 int i, count;
746 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
747 for (i=0; i<count; i++) {
748 memset(&item, 0, sizeof(LV_ITEMW));
749 item.mask = LVIF_STATE|LVIF_PARAM;
750 item.iItem = i;
751 item.stateMask = (UINT)-1;
752 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
754 if (item.state & LVIS_SELECTED) {
755 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
756 break;
759 if (pAPLI) {
760 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
761 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
763 HMODULE hUser32 = GetModuleHandleW(wszUser32);
764 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
765 if (SwitchToThisWindow) {
766 SwitchToThisWindow(pAPLI->hWnd, TRUE);
767 } else {
768 if (IsIconic(pAPLI->hWnd))
769 ShowWindow(pAPLI->hWnd, SW_RESTORE);
770 BringWindowToTop(pAPLI->hWnd);
771 SetForegroundWindow(pAPLI->hWnd);
773 if (TaskManagerSettings.MinimizeOnUse)
774 ShowWindow(hMainWnd, SW_MINIMIZE);
778 void ApplicationPage_OnEndTask(void)
780 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
781 LV_ITEMW item;
782 int i, count;
784 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
785 for (i=0; i<count; i++) {
786 memset(&item, 0, sizeof(LV_ITEMW));
787 item.mask = LVIF_STATE|LVIF_PARAM;
788 item.iItem = i;
789 item.stateMask = (UINT)-1;
790 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
791 if (item.state & LVIS_SELECTED) {
792 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
793 if (pAPLI) {
794 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
800 void ApplicationPage_OnGotoProcess(void)
802 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
803 LV_ITEMW item;
804 int i, count;
805 /* NMHDR nmhdr; */
807 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
808 for (i=0; i<count; i++) {
809 memset(&item, 0, sizeof(LV_ITEMW));
810 item.mask = LVIF_STATE|LVIF_PARAM;
811 item.iItem = i;
812 item.stateMask = (UINT)-1;
813 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
814 if (item.state & LVIS_SELECTED) {
815 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
816 break;
819 if (pAPLI) {
820 DWORD dwProcessId;
822 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
824 * Switch to the process tab
826 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 1, 0);
828 * FIXME: Select the process item in the list
833 INT_PTR CALLBACK
834 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
836 RECT rc;
837 int nXDifference;
838 int nYDifference;
839 int cx, cy;
840 LVCOLUMNW column;
842 WCHAR wszTask[255];
843 WCHAR wszStatus[255];
845 LoadStringW(hInst, IDS_APPLICATION_TASK, wszTask, sizeof(wszTask)/sizeof(WCHAR));
846 LoadStringW(hInst, IDS_APPLICATION_STATUS, wszStatus, sizeof(wszStatus)/sizeof(WCHAR));
848 switch (message) {
849 case WM_INITDIALOG:
851 /* Save the width and height */
852 GetClientRect(hDlg, &rc);
853 nApplicationPageWidth = rc.right;
854 nApplicationPageHeight = rc.bottom;
856 /* Update window position */
857 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
859 /* Get handles to the controls */
860 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
861 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
862 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
863 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
865 /* Initialize the application page's controls */
866 column.mask = LVCF_TEXT|LVCF_WIDTH;
867 column.pszText = wszTask;
868 column.cx = 250;
869 /* Add the "Task" column */
870 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM) &column);
871 column.mask = LVCF_TEXT|LVCF_WIDTH;
872 column.pszText = wszStatus;
873 column.cx = 95;
874 /* Add the "Status" column */
875 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
877 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_SMALL,
878 (LPARAM) ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1));
879 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_NORMAL,
880 (LPARAM) ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1));
882 UpdateApplicationListControlViewSetting();
884 /* Start our refresh thread */
885 CloseHandle( CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL));
887 return TRUE;
889 case WM_DESTROY:
890 /* Close the event handle, this will make the */
891 /* refresh thread exit when the wait fails */
892 CloseHandle(hApplicationPageEvent);
893 break;
895 case WM_COMMAND:
897 /* Handle the button clicks */
898 switch (LOWORD(wParam))
900 case IDC_ENDTASK:
901 ApplicationPage_OnEndTask();
902 break;
903 case IDC_SWITCHTO:
904 ApplicationPage_OnSwitchTo();
905 break;
906 case IDC_NEWTASK:
907 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
908 break;
911 break;
913 case WM_SIZE:
914 if (wParam == SIZE_MINIMIZED)
915 return 0;
917 cx = LOWORD(lParam);
918 cy = HIWORD(lParam);
919 nXDifference = cx - nApplicationPageWidth;
920 nYDifference = cy - nApplicationPageHeight;
921 nApplicationPageWidth = cx;
922 nApplicationPageHeight = cy;
924 /* Reposition the application page's controls */
925 GetWindowRect(hApplicationPageListCtrl, &rc);
926 cx = (rc.right - rc.left) + nXDifference;
927 cy = (rc.bottom - rc.top) + nYDifference;
928 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
929 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
931 GetClientRect(hApplicationPageEndTaskButton, &rc);
932 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
933 cx = rc.left + nXDifference;
934 cy = rc.top + nYDifference;
935 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
936 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
938 GetClientRect(hApplicationPageSwitchToButton, &rc);
939 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
940 cx = rc.left + nXDifference;
941 cy = rc.top + nYDifference;
942 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
943 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
945 GetClientRect(hApplicationPageNewTaskButton, &rc);
946 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
947 cx = rc.left + nXDifference;
948 cy = rc.top + nYDifference;
949 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
950 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
952 break;
954 case WM_NOTIFY:
955 ApplicationPageOnNotify(wParam, lParam);
956 break;
960 return 0;