widl: Use for_each_iface in process_tfs.
[wine.git] / programs / taskmgr / applpage.c
blobae881b530c83b4e9ad1aad7185b6c3a06cd4dde5
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, ARRAY_SIZE(wszText)) || !IsWindowVisible(hWnd) ||
253 (GetParent(hWnd) != NULL) || (GetWindow(hWnd, GW_OWNER) != NULL) ||
254 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
256 return TRUE; /* Skip this window */
259 /* Get the icon for this window */
260 hIcon = NULL;
261 SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
263 if (!hIcon)
265 hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM);
266 if (!hIcon) hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON);
267 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)&hIcon);
268 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
271 if (!hIcon)
272 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
274 bHung = FALSE;
276 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(wszUser32), "IsHungAppWindow");
278 if (IsHungAppWindow)
279 bHung = IsHungAppWindow(hWnd);
281 AddOrUpdateHwnd(hWnd, wszText, hIcon, bHung);
283 return TRUE;
286 static DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
288 /* Create the event */
289 hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
291 /* If we couldn't create the event then exit the thread */
292 if (!hApplicationPageEvent)
293 return 0;
295 while (1)
297 DWORD dwWaitVal;
299 /* Wait on the event */
300 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
302 /* If the wait failed then the event object must have been */
303 /* closed and the task manager is exiting so exit this thread */
304 if (dwWaitVal == WAIT_FAILED)
305 return 0;
307 if (dwWaitVal == WAIT_OBJECT_0)
309 /* Reset our event */
310 ResetEvent(hApplicationPageEvent);
313 * FIXME:
315 * Should this be EnumDesktopWindows() instead?
317 EnumWindows(EnumWindowsProc, 0);
322 static void ApplicationPageShowContextMenu1(void)
324 HMENU hMenu;
325 HMENU hSubMenu;
326 POINT pt;
328 GetCursorPos(&pt);
330 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
331 hSubMenu = GetSubMenu(hMenu, 0);
333 if (TaskManagerSettings.View_LargeIcons)
334 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
335 else if (TaskManagerSettings.View_SmallIcons)
336 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
337 else
338 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
340 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
342 DestroyMenu(hMenu);
345 static void ApplicationPageShowContextMenu2(void)
347 HMENU hMenu;
348 HMENU hSubMenu;
349 UINT count;
350 POINT pt;
352 GetCursorPos(&pt);
354 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
355 hSubMenu = GetSubMenu(hMenu, 0);
357 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
358 if (count == 1)
360 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
361 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
362 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
363 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
364 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
365 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
367 else if (count > 1)
369 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
370 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
371 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
372 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
373 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
374 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
376 else
378 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
379 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
380 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
381 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
382 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
383 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
386 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
388 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
390 DestroyMenu(hMenu);
393 static int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
395 LPAPPLICATION_PAGE_LIST_ITEM Param1;
396 LPAPPLICATION_PAGE_LIST_ITEM Param2;
398 if (bSortAscending) {
399 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
400 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
401 } else {
402 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
403 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
405 return strcmpW(Param1->wszTitle, Param2->wszTitle);
408 static void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
410 LPNMHDR pnmh;
411 LV_DISPINFOW* pnmdi;
412 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
413 WCHAR wszNotResponding[255];
414 WCHAR wszRunning[255];
416 LoadStringW(hInst, IDS_APPLICATION_NOT_RESPONDING, wszNotResponding, ARRAY_SIZE(wszNotResponding));
417 LoadStringW(hInst, IDS_APPLICATION_RUNNING, wszRunning, ARRAY_SIZE(wszRunning));
419 pnmh = (LPNMHDR) lParam;
420 pnmdi = (LV_DISPINFOW*) lParam;
422 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
423 switch (pnmh->code) {
424 case LVN_ITEMCHANGED:
425 ApplicationPageUpdate();
426 break;
428 case LVN_GETDISPINFOW:
429 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
431 /* Update the item text */
432 if (pnmdi->item.iSubItem == 0)
434 lstrcpynW(pnmdi->item.pszText, pAPLI->wszTitle, pnmdi->item.cchTextMax);
437 /* Update the item status */
438 else if (pnmdi->item.iSubItem == 1)
440 if (pAPLI->bHung)
441 lstrcpynW(pnmdi->item.pszText, wszNotResponding, pnmdi->item.cchTextMax);
442 else
443 lstrcpynW(pnmdi->item.pszText, wszRunning, pnmdi->item.cchTextMax);
446 break;
448 case NM_RCLICK:
450 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
452 ApplicationPageShowContextMenu1();
454 else
456 ApplicationPageShowContextMenu2();
459 break;
461 case NM_DBLCLK:
463 ApplicationPage_OnSwitchTo();
465 break;
468 else if (pnmh->hwndFrom == (HWND)SendMessageW(hApplicationPageListCtrl, LVM_GETHEADER, 0, 0))
470 switch (pnmh->code)
472 case NM_RCLICK:
474 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
476 ApplicationPageShowContextMenu1();
478 else
480 ApplicationPageShowContextMenu2();
483 break;
485 case HDN_ITEMCLICKW:
487 SendMessageW(hApplicationPageListCtrl, LVM_SORTITEMS, 0, (LPARAM) ApplicationPageCompareFunc);
488 bSortAscending = !bSortAscending;
490 break;
496 void RefreshApplicationPage(void)
498 /* Signal the event so that our refresh thread */
499 /* will wake up and refresh the application page */
500 SetEvent(hApplicationPageEvent);
503 static void UpdateApplicationListControlViewSetting(void)
505 DWORD dwStyle = GetWindowLongW(hApplicationPageListCtrl, GWL_STYLE);
507 dwStyle &= ~LVS_REPORT;
508 dwStyle &= ~LVS_ICON;
509 dwStyle &= ~LVS_LIST;
510 dwStyle &= ~LVS_SMALLICON;
512 if (TaskManagerSettings.View_LargeIcons)
513 dwStyle |= LVS_ICON;
514 else if (TaskManagerSettings.View_SmallIcons)
515 dwStyle |= LVS_SMALLICON;
516 else
517 dwStyle |= LVS_REPORT;
519 SetWindowLongW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
521 RefreshApplicationPage();
524 void ApplicationPage_OnViewLargeIcons(void)
526 HMENU hMenu;
527 HMENU hViewMenu;
529 hMenu = GetMenu(hMainWnd);
530 hViewMenu = GetSubMenu(hMenu, 2);
532 TaskManagerSettings.View_LargeIcons = TRUE;
533 TaskManagerSettings.View_SmallIcons = FALSE;
534 TaskManagerSettings.View_Details = FALSE;
535 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
537 UpdateApplicationListControlViewSetting();
540 void ApplicationPage_OnViewSmallIcons(void)
542 HMENU hMenu;
543 HMENU hViewMenu;
545 hMenu = GetMenu(hMainWnd);
546 hViewMenu = GetSubMenu(hMenu, 2);
548 TaskManagerSettings.View_LargeIcons = FALSE;
549 TaskManagerSettings.View_SmallIcons = TRUE;
550 TaskManagerSettings.View_Details = FALSE;
551 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
553 UpdateApplicationListControlViewSetting();
556 void ApplicationPage_OnViewDetails(void)
558 HMENU hMenu;
559 HMENU hViewMenu;
561 hMenu = GetMenu(hMainWnd);
562 hViewMenu = GetSubMenu(hMenu, 2);
564 TaskManagerSettings.View_LargeIcons = FALSE;
565 TaskManagerSettings.View_SmallIcons = FALSE;
566 TaskManagerSettings.View_Details = TRUE;
567 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
569 UpdateApplicationListControlViewSetting();
572 void ApplicationPage_OnWindowsTileHorizontally(void)
574 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
575 LV_ITEMW item;
576 int i, count;
577 HWND* hWndArray;
578 int nWndCount;
580 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
581 hWndArray = HeapAlloc(GetProcessHeap(), 0,
582 sizeof(HWND) * count);
583 nWndCount = 0;
585 for (i=0; i<count; i++) {
586 memset(&item, 0, sizeof(LV_ITEMW));
587 item.mask = LVIF_STATE|LVIF_PARAM;
588 item.iItem = i;
589 item.stateMask = (UINT)-1;
590 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
592 if (item.state & LVIS_SELECTED) {
593 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
595 if (pAPLI) {
596 hWndArray[nWndCount] = pAPLI->hWnd;
597 nWndCount++;
601 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
602 HeapFree(GetProcessHeap(), 0, hWndArray);
605 void ApplicationPage_OnWindowsTileVertically(void)
607 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
608 LV_ITEMW item;
609 int i, count;
610 HWND* hWndArray;
611 int nWndCount;
613 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
614 hWndArray = HeapAlloc(GetProcessHeap(), 0,
615 sizeof(HWND) * count);
616 nWndCount = 0;
618 for (i=0; i<count; i++) {
619 memset(&item, 0, sizeof(LV_ITEMW));
620 item.mask = LVIF_STATE|LVIF_PARAM;
621 item.iItem = i;
622 item.stateMask = (UINT)-1;
623 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
625 if (item.state & LVIS_SELECTED) {
626 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
627 if (pAPLI) {
628 hWndArray[nWndCount] = pAPLI->hWnd;
629 nWndCount++;
634 TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
635 HeapFree(GetProcessHeap(), 0, hWndArray);
638 void ApplicationPage_OnWindowsMinimize(void)
640 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
641 LV_ITEMW item;
642 int i, count;
644 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
645 for (i=0; i<count; i++) {
646 memset(&item, 0, sizeof(LV_ITEMW));
647 item.mask = LVIF_STATE|LVIF_PARAM;
648 item.iItem = i;
649 item.stateMask = (UINT)-1;
650 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
651 if (item.state & LVIS_SELECTED) {
652 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
653 if (pAPLI) {
654 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
660 void ApplicationPage_OnWindowsMaximize(void)
662 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
663 LV_ITEMW item;
664 int i, count;
666 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
667 for (i=0; i<count; i++) {
668 memset(&item, 0, sizeof(LV_ITEMW));
669 item.mask = LVIF_STATE|LVIF_PARAM;
670 item.iItem = i;
671 item.stateMask = (UINT)-1;
672 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
673 if (item.state & LVIS_SELECTED) {
674 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
675 if (pAPLI) {
676 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
682 void ApplicationPage_OnWindowsCascade(void)
684 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
685 LV_ITEMW item;
686 int i, count;
687 HWND* hWndArray;
688 int nWndCount;
690 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
691 hWndArray = HeapAlloc(GetProcessHeap(), 0,
692 sizeof(HWND) * count);
693 nWndCount = 0;
695 for (i=0; i<count; i++) {
696 memset(&item, 0, sizeof(LV_ITEMW));
697 item.mask = LVIF_STATE|LVIF_PARAM;
698 item.iItem = i;
699 item.stateMask = (UINT)-1;
700 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
701 if (item.state & LVIS_SELECTED) {
702 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
703 if (pAPLI) {
704 hWndArray[nWndCount] = pAPLI->hWnd;
705 nWndCount++;
709 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
710 HeapFree(GetProcessHeap(), 0, hWndArray);
713 void ApplicationPage_OnWindowsBringToFront(void)
715 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
716 LV_ITEMW item;
717 int i, count;
719 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
720 for (i=0; i<count; i++) {
721 memset(&item, 0, sizeof(LV_ITEMW));
722 item.mask = LVIF_STATE|LVIF_PARAM;
723 item.iItem = i;
724 item.stateMask = (UINT)-1;
725 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
726 if (item.state & LVIS_SELECTED) {
727 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
728 break;
731 if (pAPLI) {
732 if (IsIconic(pAPLI->hWnd))
733 ShowWindow(pAPLI->hWnd, SW_RESTORE);
734 BringWindowToTop(pAPLI->hWnd);
738 void ApplicationPage_OnSwitchTo(void)
740 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
741 LV_ITEMW item;
742 int i, count;
744 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
745 for (i=0; i<count; i++) {
746 memset(&item, 0, sizeof(LV_ITEMW));
747 item.mask = LVIF_STATE|LVIF_PARAM;
748 item.iItem = i;
749 item.stateMask = (UINT)-1;
750 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
752 if (item.state & LVIS_SELECTED) {
753 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
754 break;
757 if (pAPLI) {
758 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
759 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
761 HMODULE hUser32 = GetModuleHandleW(wszUser32);
762 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
763 if (SwitchToThisWindow) {
764 SwitchToThisWindow(pAPLI->hWnd, TRUE);
765 } else {
766 if (IsIconic(pAPLI->hWnd))
767 ShowWindow(pAPLI->hWnd, SW_RESTORE);
768 BringWindowToTop(pAPLI->hWnd);
769 SetForegroundWindow(pAPLI->hWnd);
771 if (TaskManagerSettings.MinimizeOnUse)
772 ShowWindow(hMainWnd, SW_MINIMIZE);
776 void ApplicationPage_OnEndTask(void)
778 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
779 LV_ITEMW item;
780 int i, count;
782 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
783 for (i=0; i<count; i++) {
784 memset(&item, 0, sizeof(LV_ITEMW));
785 item.mask = LVIF_STATE|LVIF_PARAM;
786 item.iItem = i;
787 item.stateMask = (UINT)-1;
788 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
789 if (item.state & LVIS_SELECTED) {
790 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
791 if (pAPLI) {
792 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
798 void ApplicationPage_OnGotoProcess(void)
800 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
801 LV_ITEMW item;
802 int i, count;
803 /* NMHDR nmhdr; */
805 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
806 for (i=0; i<count; i++) {
807 memset(&item, 0, sizeof(LV_ITEMW));
808 item.mask = LVIF_STATE|LVIF_PARAM;
809 item.iItem = i;
810 item.stateMask = (UINT)-1;
811 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
812 if (item.state & LVIS_SELECTED) {
813 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
814 break;
817 if (pAPLI) {
818 DWORD dwProcessId;
820 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
822 * Switch to the process tab
824 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 1, 0);
826 * FIXME: Select the process item in the list
831 INT_PTR CALLBACK
832 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
834 RECT rc;
835 int nXDifference;
836 int nYDifference;
837 int cx, cy;
838 LVCOLUMNW column;
840 WCHAR wszTask[255];
841 WCHAR wszStatus[255];
843 LoadStringW(hInst, IDS_APPLICATION_TASK, wszTask, ARRAY_SIZE(wszTask));
844 LoadStringW(hInst, IDS_APPLICATION_STATUS, wszStatus, ARRAY_SIZE(wszStatus));
846 switch (message) {
847 case WM_INITDIALOG:
849 /* Save the width and height */
850 GetClientRect(hDlg, &rc);
851 nApplicationPageWidth = rc.right;
852 nApplicationPageHeight = rc.bottom;
854 /* Update window position */
855 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
857 /* Get handles to the controls */
858 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
859 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
860 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
861 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
863 /* Initialize the application page's controls */
864 column.mask = LVCF_TEXT|LVCF_WIDTH;
865 column.pszText = wszTask;
866 column.cx = 250;
867 /* Add the "Task" column */
868 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM) &column);
869 column.mask = LVCF_TEXT|LVCF_WIDTH;
870 column.pszText = wszStatus;
871 column.cx = 95;
872 /* Add the "Status" column */
873 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
875 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_SMALL,
876 (LPARAM) ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1));
877 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_NORMAL,
878 (LPARAM) ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1));
880 UpdateApplicationListControlViewSetting();
882 /* Start our refresh thread */
883 CloseHandle( CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL));
885 return TRUE;
887 case WM_DESTROY:
888 /* Close the event handle, this will make the */
889 /* refresh thread exit when the wait fails */
890 CloseHandle(hApplicationPageEvent);
891 break;
893 case WM_COMMAND:
895 /* Handle the button clicks */
896 switch (LOWORD(wParam))
898 case IDC_ENDTASK:
899 ApplicationPage_OnEndTask();
900 break;
901 case IDC_SWITCHTO:
902 ApplicationPage_OnSwitchTo();
903 break;
904 case IDC_NEWTASK:
905 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
906 break;
909 break;
911 case WM_SIZE:
912 if (wParam == SIZE_MINIMIZED)
913 return 0;
915 cx = LOWORD(lParam);
916 cy = HIWORD(lParam);
917 nXDifference = cx - nApplicationPageWidth;
918 nYDifference = cy - nApplicationPageHeight;
919 nApplicationPageWidth = cx;
920 nApplicationPageHeight = cy;
922 /* Reposition the application page's controls */
923 GetWindowRect(hApplicationPageListCtrl, &rc);
924 cx = (rc.right - rc.left) + nXDifference;
925 cy = (rc.bottom - rc.top) + nYDifference;
926 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
927 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
929 GetClientRect(hApplicationPageEndTaskButton, &rc);
930 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
931 cx = rc.left + nXDifference;
932 cy = rc.top + nYDifference;
933 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
934 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
936 GetClientRect(hApplicationPageSwitchToButton, &rc);
937 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
938 cx = rc.left + nXDifference;
939 cy = rc.top + nYDifference;
940 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
941 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
943 GetClientRect(hApplicationPageNewTaskButton, &rc);
944 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
945 cx = rc.left + nXDifference;
946 cy = rc.top + nYDifference;
947 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
948 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
950 break;
952 case WM_NOTIFY:
953 ApplicationPageOnNotify(wParam, lParam);
954 break;
958 return 0;