msvcp100: Don't bother to clean up at process exit.
[wine.git] / programs / taskmgr / applpage.c
blobc7debecce4cfda1fbd2348a181aa0674fae8debe
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};
52 #if 0
53 void SwitchToThisWindow (
54 HWND hWnd, /* Handle to the window that should be activated */
55 BOOL bRestore /* Restore the window if it is minimized */
57 #endif
59 static void ApplicationPageUpdate(void)
61 /* Enable or disable the "End Task" & "Switch To" buttons */
62 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0))
64 EnableWindow(hApplicationPageEndTaskButton, TRUE);
65 EnableWindow(hApplicationPageSwitchToButton, TRUE);
67 else
69 EnableWindow(hApplicationPageEndTaskButton, FALSE);
70 EnableWindow(hApplicationPageSwitchToButton, FALSE);
73 /* If we are on the applications tab, then the windows menu will */
74 /* be present on the menu bar so enable & disable the menu items */
75 if (SendMessageW(hTabWnd, TCM_GETCURSEL, 0, 0) == 0)
77 HMENU hMenu;
78 HMENU hWindowsMenu;
79 UINT count;
81 hMenu = GetMenu(hMainWnd);
82 hWindowsMenu = GetSubMenu(hMenu, 3);
83 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
85 /* Only one item selected */
86 if (count == 1)
88 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
89 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
90 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
91 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
92 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
93 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
95 /* More than one item selected */
96 else if (count > 1)
98 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
99 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
100 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
101 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
102 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
103 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
105 /* No items selected */
106 else
108 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
109 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
110 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
111 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
112 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
113 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
118 static void AddOrUpdateHwnd(HWND hWnd, WCHAR *wszTitle, HICON hIcon, BOOL bHung)
120 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
121 HIMAGELIST hImageListLarge;
122 HIMAGELIST hImageListSmall;
123 LV_ITEMW item;
124 int i, count;
125 BOOL bAlreadyInList = FALSE;
126 BOOL bItemRemoved = FALSE;
128 memset(&item, 0, sizeof(LV_ITEMW));
130 /* Get the image lists */
131 hImageListLarge = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_NORMAL, 0);
132 hImageListSmall = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_SMALL, 0);
134 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
135 /* Check to see if it's already in our list */
136 for (i=0; i<count; i++)
138 memset(&item, 0, sizeof(LV_ITEMW));
139 item.mask = LVIF_IMAGE|LVIF_PARAM;
140 item.iItem = i;
141 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
143 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
144 if (pAPLI->hWnd == hWnd)
146 bAlreadyInList = TRUE;
147 break;
151 /* If it is already in the list then update it if necessary */
152 if (bAlreadyInList)
154 /* Check to see if anything needs updating */
155 if ((pAPLI->hIcon != hIcon) ||
156 (strcmpW(pAPLI->wszTitle, wszTitle) != 0) ||
157 (pAPLI->bHung != bHung))
159 /* Update the structure */
160 pAPLI->hIcon = hIcon;
161 pAPLI->bHung = bHung;
162 strcpyW(pAPLI->wszTitle, wszTitle);
164 /* Update the image list */
165 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
166 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
168 /* Update the list view */
169 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
170 SendMessageW(hApplicationPageListCtrl, LVM_REDRAWITEMS, 0, count);
171 /* UpdateWindow(hApplicationPageListCtrl); */
172 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
175 /* It is not already in the list so add it */
176 else
178 pAPLI = HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
180 pAPLI->hWnd = hWnd;
181 pAPLI->hIcon = hIcon;
182 pAPLI->bHung = bHung;
183 strcpyW(pAPLI->wszTitle, wszTitle);
185 /* Add the item to the list */
186 memset(&item, 0, sizeof(LV_ITEMW));
187 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
188 ImageList_AddIcon(hImageListLarge, hIcon);
189 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
190 item.pszText = LPSTR_TEXTCALLBACKW;
191 item.iItem = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
192 item.lParam = (LPARAM)pAPLI;
193 SendMessageW(hApplicationPageListCtrl, LVM_INSERTITEMW, 0, (LPARAM) &item);
197 /* Check to see if we need to remove any items from the list */
198 for (i=SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0)-1; i>=0; i--)
200 memset(&item, 0, sizeof(LV_ITEMW));
201 item.mask = LVIF_IMAGE|LVIF_PARAM;
202 item.iItem = i;
203 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
205 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
206 if (!IsWindow(pAPLI->hWnd)||
207 (strlenW(pAPLI->wszTitle) <= 0) ||
208 !IsWindowVisible(pAPLI->hWnd) ||
209 (GetParent(pAPLI->hWnd) != NULL) ||
210 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
211 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
213 ImageList_Remove(hImageListLarge, item.iItem);
214 ImageList_Remove(hImageListSmall, item.iItem);
216 SendMessageW(hApplicationPageListCtrl, LVM_DELETEITEM, item.iItem, 0);
217 HeapFree(GetProcessHeap(), 0, pAPLI);
218 bItemRemoved = TRUE;
223 * If an item was removed from the list then
224 * we need to resync all the items with the
225 * image list
227 if (bItemRemoved)
229 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
230 for (i=0; i<count; i++)
232 memset(&item, 0, sizeof(LV_ITEMW));
233 item.mask = LVIF_IMAGE;
234 item.iItem = i;
235 item.iImage = i;
236 SendMessageW(hApplicationPageListCtrl, LVM_SETITEMW, 0, (LPARAM) &item);
240 ApplicationPageUpdate();
243 static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
245 HICON hIcon;
246 WCHAR wszText[256];
247 BOOL bLargeIcon = TaskManagerSettings.View_LargeIcons;
248 BOOL bHung = FALSE;
249 typedef int (__stdcall *IsHungAppWindowProc)(HWND);
250 IsHungAppWindowProc IsHungAppWindow;
253 /* Skip our window */
254 if (hWnd == hMainWnd)
255 return TRUE;
257 /* Check and see if this is a top-level app window */
258 if (!GetWindowTextW(hWnd, wszText, sizeof(wszText)/sizeof(WCHAR)) ||
259 !IsWindowVisible(hWnd) ||
260 (GetParent(hWnd) != NULL) ||
261 (GetWindow(hWnd, GW_OWNER) != NULL) ||
262 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
264 return TRUE; /* Skip this window */
267 /* Get the icon for this window */
268 hIcon = NULL;
269 SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
271 if (!hIcon)
273 hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM);
274 if (!hIcon) hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON);
275 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)&hIcon);
276 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
279 if (!hIcon)
280 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
282 bHung = FALSE;
284 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(wszUser32), "IsHungAppWindow");
286 if (IsHungAppWindow)
287 bHung = IsHungAppWindow(hWnd);
289 AddOrUpdateHwnd(hWnd, wszText, hIcon, bHung);
291 return TRUE;
294 static DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
296 /* Create the event */
297 hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
299 /* If we couldn't create the event then exit the thread */
300 if (!hApplicationPageEvent)
301 return 0;
303 while (1)
305 DWORD dwWaitVal;
307 /* Wait on the event */
308 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
310 /* If the wait failed then the event object must have been */
311 /* closed and the task manager is exiting so exit this thread */
312 if (dwWaitVal == WAIT_FAILED)
313 return 0;
315 if (dwWaitVal == WAIT_OBJECT_0)
317 /* Reset our event */
318 ResetEvent(hApplicationPageEvent);
321 * FIXME:
323 * Should this be EnumDesktopWindows() instead?
325 EnumWindows(EnumWindowsProc, 0);
330 static void ApplicationPageShowContextMenu1(void)
332 HMENU hMenu;
333 HMENU hSubMenu;
334 POINT pt;
336 GetCursorPos(&pt);
338 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
339 hSubMenu = GetSubMenu(hMenu, 0);
341 if (TaskManagerSettings.View_LargeIcons)
342 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
343 else if (TaskManagerSettings.View_SmallIcons)
344 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
345 else
346 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
348 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
350 DestroyMenu(hMenu);
353 static void ApplicationPageShowContextMenu2(void)
355 HMENU hMenu;
356 HMENU hSubMenu;
357 UINT count;
358 POINT pt;
360 GetCursorPos(&pt);
362 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
363 hSubMenu = GetSubMenu(hMenu, 0);
365 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
366 if (count == 1)
368 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
369 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
370 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
371 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
372 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
373 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
375 else if (count > 1)
377 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
378 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
379 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
380 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
381 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
382 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
384 else
386 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
387 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
388 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
389 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
390 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
391 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
394 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
396 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
398 DestroyMenu(hMenu);
401 static int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
403 LPAPPLICATION_PAGE_LIST_ITEM Param1;
404 LPAPPLICATION_PAGE_LIST_ITEM Param2;
406 if (bSortAscending) {
407 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
408 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
409 } else {
410 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
411 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
413 return strcmpW(Param1->wszTitle, Param2->wszTitle);
416 static void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
418 LPNMHDR pnmh;
419 LV_DISPINFOW* pnmdi;
420 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
421 WCHAR wszNotResponding[255];
422 WCHAR wszRunning[255];
424 LoadStringW(hInst, IDS_APPLICATION_NOT_RESPONDING, wszNotResponding, sizeof(wszNotResponding)/sizeof(WCHAR));
425 LoadStringW(hInst, IDS_APPLICATION_RUNNING, wszRunning, sizeof(wszRunning)/sizeof(WCHAR));
427 pnmh = (LPNMHDR) lParam;
428 pnmdi = (LV_DISPINFOW*) lParam;
430 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
431 switch (pnmh->code) {
432 case LVN_ITEMCHANGED:
433 ApplicationPageUpdate();
434 break;
436 case LVN_GETDISPINFOW:
437 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
439 /* Update the item text */
440 if (pnmdi->item.iSubItem == 0)
442 lstrcpynW(pnmdi->item.pszText, pAPLI->wszTitle, pnmdi->item.cchTextMax);
445 /* Update the item status */
446 else if (pnmdi->item.iSubItem == 1)
448 if (pAPLI->bHung)
449 lstrcpynW(pnmdi->item.pszText, wszNotResponding, pnmdi->item.cchTextMax);
450 else
451 lstrcpynW(pnmdi->item.pszText, wszRunning, pnmdi->item.cchTextMax);
454 break;
456 case NM_RCLICK:
458 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
460 ApplicationPageShowContextMenu1();
462 else
464 ApplicationPageShowContextMenu2();
467 break;
469 case NM_DBLCLK:
471 ApplicationPage_OnSwitchTo();
473 break;
476 else if (pnmh->hwndFrom == (HWND)SendMessageW(hApplicationPageListCtrl, LVM_GETHEADER, 0, 0))
478 switch (pnmh->code)
480 case NM_RCLICK:
482 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
484 ApplicationPageShowContextMenu1();
486 else
488 ApplicationPageShowContextMenu2();
491 break;
493 case HDN_ITEMCLICKW:
495 SendMessageW(hApplicationPageListCtrl, LVM_SORTITEMS, 0, (LPARAM) ApplicationPageCompareFunc);
496 bSortAscending = !bSortAscending;
498 break;
504 void RefreshApplicationPage(void)
506 /* Signal the event so that our refresh thread */
507 /* will wake up and refresh the application page */
508 SetEvent(hApplicationPageEvent);
511 static void UpdateApplicationListControlViewSetting(void)
513 DWORD dwStyle = GetWindowLongW(hApplicationPageListCtrl, GWL_STYLE);
515 dwStyle &= ~LVS_REPORT;
516 dwStyle &= ~LVS_ICON;
517 dwStyle &= ~LVS_LIST;
518 dwStyle &= ~LVS_SMALLICON;
520 if (TaskManagerSettings.View_LargeIcons)
521 dwStyle |= LVS_ICON;
522 else if (TaskManagerSettings.View_SmallIcons)
523 dwStyle |= LVS_SMALLICON;
524 else
525 dwStyle |= LVS_REPORT;
527 SetWindowLongW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
529 RefreshApplicationPage();
532 void ApplicationPage_OnViewLargeIcons(void)
534 HMENU hMenu;
535 HMENU hViewMenu;
537 hMenu = GetMenu(hMainWnd);
538 hViewMenu = GetSubMenu(hMenu, 2);
540 TaskManagerSettings.View_LargeIcons = TRUE;
541 TaskManagerSettings.View_SmallIcons = FALSE;
542 TaskManagerSettings.View_Details = FALSE;
543 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
545 UpdateApplicationListControlViewSetting();
548 void ApplicationPage_OnViewSmallIcons(void)
550 HMENU hMenu;
551 HMENU hViewMenu;
553 hMenu = GetMenu(hMainWnd);
554 hViewMenu = GetSubMenu(hMenu, 2);
556 TaskManagerSettings.View_LargeIcons = FALSE;
557 TaskManagerSettings.View_SmallIcons = TRUE;
558 TaskManagerSettings.View_Details = FALSE;
559 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
561 UpdateApplicationListControlViewSetting();
564 void ApplicationPage_OnViewDetails(void)
566 HMENU hMenu;
567 HMENU hViewMenu;
569 hMenu = GetMenu(hMainWnd);
570 hViewMenu = GetSubMenu(hMenu, 2);
572 TaskManagerSettings.View_LargeIcons = FALSE;
573 TaskManagerSettings.View_SmallIcons = FALSE;
574 TaskManagerSettings.View_Details = TRUE;
575 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
577 UpdateApplicationListControlViewSetting();
580 void ApplicationPage_OnWindowsTileHorizontally(void)
582 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
583 LV_ITEMW item;
584 int i, count;
585 HWND* hWndArray;
586 int nWndCount;
588 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
589 hWndArray = HeapAlloc(GetProcessHeap(), 0,
590 sizeof(HWND) * count);
591 nWndCount = 0;
593 for (i=0; i<count; i++) {
594 memset(&item, 0, sizeof(LV_ITEMW));
595 item.mask = LVIF_STATE|LVIF_PARAM;
596 item.iItem = i;
597 item.stateMask = (UINT)-1;
598 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
600 if (item.state & LVIS_SELECTED) {
601 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
603 if (pAPLI) {
604 hWndArray[nWndCount] = pAPLI->hWnd;
605 nWndCount++;
609 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
610 HeapFree(GetProcessHeap(), 0, hWndArray);
613 void ApplicationPage_OnWindowsTileVertically(void)
615 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
616 LV_ITEMW item;
617 int i, count;
618 HWND* hWndArray;
619 int nWndCount;
621 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
622 hWndArray = HeapAlloc(GetProcessHeap(), 0,
623 sizeof(HWND) * count);
624 nWndCount = 0;
626 for (i=0; i<count; i++) {
627 memset(&item, 0, sizeof(LV_ITEMW));
628 item.mask = LVIF_STATE|LVIF_PARAM;
629 item.iItem = i;
630 item.stateMask = (UINT)-1;
631 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
633 if (item.state & LVIS_SELECTED) {
634 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
635 if (pAPLI) {
636 hWndArray[nWndCount] = pAPLI->hWnd;
637 nWndCount++;
642 TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
643 HeapFree(GetProcessHeap(), 0, hWndArray);
646 void ApplicationPage_OnWindowsMinimize(void)
648 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
649 LV_ITEMW item;
650 int i, count;
652 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
653 for (i=0; i<count; i++) {
654 memset(&item, 0, sizeof(LV_ITEMW));
655 item.mask = LVIF_STATE|LVIF_PARAM;
656 item.iItem = i;
657 item.stateMask = (UINT)-1;
658 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
659 if (item.state & LVIS_SELECTED) {
660 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
661 if (pAPLI) {
662 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
668 void ApplicationPage_OnWindowsMaximize(void)
670 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
671 LV_ITEMW item;
672 int i, count;
674 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
675 for (i=0; i<count; i++) {
676 memset(&item, 0, sizeof(LV_ITEMW));
677 item.mask = LVIF_STATE|LVIF_PARAM;
678 item.iItem = i;
679 item.stateMask = (UINT)-1;
680 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
681 if (item.state & LVIS_SELECTED) {
682 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
683 if (pAPLI) {
684 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
690 void ApplicationPage_OnWindowsCascade(void)
692 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
693 LV_ITEMW item;
694 int i, count;
695 HWND* hWndArray;
696 int nWndCount;
698 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
699 hWndArray = HeapAlloc(GetProcessHeap(), 0,
700 sizeof(HWND) * count);
701 nWndCount = 0;
703 for (i=0; i<count; i++) {
704 memset(&item, 0, sizeof(LV_ITEMW));
705 item.mask = LVIF_STATE|LVIF_PARAM;
706 item.iItem = i;
707 item.stateMask = (UINT)-1;
708 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
709 if (item.state & LVIS_SELECTED) {
710 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
711 if (pAPLI) {
712 hWndArray[nWndCount] = pAPLI->hWnd;
713 nWndCount++;
717 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
718 HeapFree(GetProcessHeap(), 0, hWndArray);
721 void ApplicationPage_OnWindowsBringToFront(void)
723 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
724 LV_ITEMW item;
725 int i, count;
727 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
728 for (i=0; i<count; i++) {
729 memset(&item, 0, sizeof(LV_ITEMW));
730 item.mask = LVIF_STATE|LVIF_PARAM;
731 item.iItem = i;
732 item.stateMask = (UINT)-1;
733 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
734 if (item.state & LVIS_SELECTED) {
735 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
736 break;
739 if (pAPLI) {
740 if (IsIconic(pAPLI->hWnd))
741 ShowWindow(pAPLI->hWnd, SW_RESTORE);
742 BringWindowToTop(pAPLI->hWnd);
746 void ApplicationPage_OnSwitchTo(void)
748 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
749 LV_ITEMW item;
750 int i, count;
752 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
753 for (i=0; i<count; i++) {
754 memset(&item, 0, sizeof(LV_ITEMW));
755 item.mask = LVIF_STATE|LVIF_PARAM;
756 item.iItem = i;
757 item.stateMask = (UINT)-1;
758 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
760 if (item.state & LVIS_SELECTED) {
761 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
762 break;
765 if (pAPLI) {
766 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
767 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
769 HMODULE hUser32 = GetModuleHandleW(wszUser32);
770 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
771 if (SwitchToThisWindow) {
772 SwitchToThisWindow(pAPLI->hWnd, TRUE);
773 } else {
774 if (IsIconic(pAPLI->hWnd))
775 ShowWindow(pAPLI->hWnd, SW_RESTORE);
776 BringWindowToTop(pAPLI->hWnd);
777 SetForegroundWindow(pAPLI->hWnd);
779 if (TaskManagerSettings.MinimizeOnUse)
780 ShowWindow(hMainWnd, SW_MINIMIZE);
784 void ApplicationPage_OnEndTask(void)
786 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
787 LV_ITEMW item;
788 int i, count;
790 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
791 for (i=0; i<count; i++) {
792 memset(&item, 0, sizeof(LV_ITEMW));
793 item.mask = LVIF_STATE|LVIF_PARAM;
794 item.iItem = i;
795 item.stateMask = (UINT)-1;
796 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
797 if (item.state & LVIS_SELECTED) {
798 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
799 if (pAPLI) {
800 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
806 void ApplicationPage_OnGotoProcess(void)
808 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
809 LV_ITEMW item;
810 int i, count;
811 /* NMHDR nmhdr; */
813 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
814 for (i=0; i<count; i++) {
815 memset(&item, 0, sizeof(LV_ITEMW));
816 item.mask = LVIF_STATE|LVIF_PARAM;
817 item.iItem = i;
818 item.stateMask = (UINT)-1;
819 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
820 if (item.state & LVIS_SELECTED) {
821 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
822 break;
825 if (pAPLI) {
826 DWORD dwProcessId;
828 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
830 * Switch to the process tab
832 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 1, 0);
834 * FIXME: Select the process item in the list
839 INT_PTR CALLBACK
840 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
842 RECT rc;
843 int nXDifference;
844 int nYDifference;
845 int cx, cy;
846 LVCOLUMNW column;
848 WCHAR wszTask[255];
849 WCHAR wszStatus[255];
851 LoadStringW(hInst, IDS_APPLICATION_TASK, wszTask, sizeof(wszTask)/sizeof(WCHAR));
852 LoadStringW(hInst, IDS_APPLICATION_STATUS, wszStatus, sizeof(wszStatus)/sizeof(WCHAR));
854 switch (message) {
855 case WM_INITDIALOG:
857 /* Save the width and height */
858 GetClientRect(hDlg, &rc);
859 nApplicationPageWidth = rc.right;
860 nApplicationPageHeight = rc.bottom;
862 /* Update window position */
863 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
865 /* Get handles to the controls */
866 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
867 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
868 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
869 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
871 /* Initialize the application page's controls */
872 column.mask = LVCF_TEXT|LVCF_WIDTH;
873 column.pszText = wszTask;
874 column.cx = 250;
875 /* Add the "Task" column */
876 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM) &column);
877 column.mask = LVCF_TEXT|LVCF_WIDTH;
878 column.pszText = wszStatus;
879 column.cx = 95;
880 /* Add the "Status" column */
881 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
883 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_SMALL,
884 (LPARAM) ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1));
885 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_NORMAL,
886 (LPARAM) ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1));
888 UpdateApplicationListControlViewSetting();
890 /* Start our refresh thread */
891 CloseHandle( CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL));
893 return TRUE;
895 case WM_DESTROY:
896 /* Close the event handle, this will make the */
897 /* refresh thread exit when the wait fails */
898 CloseHandle(hApplicationPageEvent);
899 break;
901 case WM_COMMAND:
903 /* Handle the button clicks */
904 switch (LOWORD(wParam))
906 case IDC_ENDTASK:
907 ApplicationPage_OnEndTask();
908 break;
909 case IDC_SWITCHTO:
910 ApplicationPage_OnSwitchTo();
911 break;
912 case IDC_NEWTASK:
913 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
914 break;
917 break;
919 case WM_SIZE:
920 if (wParam == SIZE_MINIMIZED)
921 return 0;
923 cx = LOWORD(lParam);
924 cy = HIWORD(lParam);
925 nXDifference = cx - nApplicationPageWidth;
926 nYDifference = cy - nApplicationPageHeight;
927 nApplicationPageWidth = cx;
928 nApplicationPageHeight = cy;
930 /* Reposition the application page's controls */
931 GetWindowRect(hApplicationPageListCtrl, &rc);
932 cx = (rc.right - rc.left) + nXDifference;
933 cy = (rc.bottom - rc.top) + nYDifference;
934 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
935 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
937 GetClientRect(hApplicationPageEndTaskButton, &rc);
938 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
939 cx = rc.left + nXDifference;
940 cy = rc.top + nYDifference;
941 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
942 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
944 GetClientRect(hApplicationPageSwitchToButton, &rc);
945 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
946 cx = rc.left + nXDifference;
947 cy = rc.top + nYDifference;
948 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
949 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
951 GetClientRect(hApplicationPageNewTaskButton, &rc);
952 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
953 cx = rc.left + nXDifference;
954 cy = rc.top + nYDifference;
955 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
956 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
958 break;
960 case WM_NOTIFY:
961 ApplicationPageOnNotify(wParam, lParam);
962 break;
966 return 0;