gdi32: Use free_gdi_handle directly for NtGdiDeleteClientObj.
[wine.git] / programs / taskmgr / applpage.c
blobb35881c2323bad5b84fe5a972edf3aa8ce25d75b
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 "taskmgr.h"
32 typedef struct
34 HWND hWnd;
35 WCHAR wszTitle[256];
36 HICON hIcon;
37 BOOL bHung;
38 } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM;
40 HWND hApplicationPage; /* Application List Property Page */
41 HWND hApplicationPageListCtrl; /* Application ListCtrl Window */
42 HWND hApplicationPageEndTaskButton; /* Application End Task button */
43 HWND hApplicationPageSwitchToButton; /* Application Switch To button */
44 HWND hApplicationPageNewTaskButton; /* Application New Task button */
45 static int nApplicationPageWidth;
46 static int nApplicationPageHeight;
47 static HANDLE hApplicationPageEvent = NULL; /* When this event becomes signaled then we refresh the app list */
48 static BOOL bSortAscending = TRUE;
50 static void ApplicationPageUpdate(void)
52 /* Enable or disable the "End Task" & "Switch To" buttons */
53 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0))
55 EnableWindow(hApplicationPageEndTaskButton, TRUE);
56 EnableWindow(hApplicationPageSwitchToButton, TRUE);
58 else
60 EnableWindow(hApplicationPageEndTaskButton, FALSE);
61 EnableWindow(hApplicationPageSwitchToButton, FALSE);
64 /* If we are on the applications tab, then the windows menu will */
65 /* be present on the menu bar so enable & disable the menu items */
66 if (SendMessageW(hTabWnd, TCM_GETCURSEL, 0, 0) == 0)
68 HMENU hMenu;
69 HMENU hWindowsMenu;
70 UINT count;
72 hMenu = GetMenu(hMainWnd);
73 hWindowsMenu = GetSubMenu(hMenu, 3);
74 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
76 /* Only one item selected */
77 if (count == 1)
79 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
80 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
81 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
82 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
83 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
84 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
86 /* More than one item selected */
87 else if (count > 1)
89 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
90 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
91 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
92 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
93 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
94 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
96 /* No items selected */
97 else
99 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
100 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
101 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
102 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
103 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
104 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
109 static void AddOrUpdateHwnd(HWND hWnd, WCHAR *wszTitle, HICON hIcon, BOOL bHung)
111 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
112 HIMAGELIST hImageListLarge;
113 HIMAGELIST hImageListSmall;
114 LV_ITEMW item;
115 int i, count;
116 BOOL bAlreadyInList = FALSE;
117 BOOL bItemRemoved = FALSE;
119 memset(&item, 0, sizeof(LV_ITEMW));
121 /* Get the image lists */
122 hImageListLarge = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_NORMAL, 0);
123 hImageListSmall = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_SMALL, 0);
125 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
126 /* Check to see if it's already in our list */
127 for (i=0; i<count; i++)
129 memset(&item, 0, sizeof(LV_ITEMW));
130 item.mask = LVIF_IMAGE|LVIF_PARAM;
131 item.iItem = i;
132 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
134 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
135 if (pAPLI->hWnd == hWnd)
137 bAlreadyInList = TRUE;
138 break;
142 /* If it is already in the list then update it if necessary */
143 if (bAlreadyInList)
145 /* Check to see if anything needs updating */
146 if ((pAPLI->hIcon != hIcon) ||
147 (lstrcmpW(pAPLI->wszTitle, wszTitle) != 0) ||
148 (pAPLI->bHung != bHung))
150 /* Update the structure */
151 pAPLI->hIcon = hIcon;
152 pAPLI->bHung = bHung;
153 lstrcpyW(pAPLI->wszTitle, wszTitle);
155 /* Update the image list */
156 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
157 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
159 /* Update the list view */
160 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
161 SendMessageW(hApplicationPageListCtrl, LVM_REDRAWITEMS, 0, count);
162 /* UpdateWindow(hApplicationPageListCtrl); */
163 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
166 /* It is not already in the list so add it */
167 else
169 pAPLI = HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
171 pAPLI->hWnd = hWnd;
172 pAPLI->hIcon = hIcon;
173 pAPLI->bHung = bHung;
174 lstrcpyW(pAPLI->wszTitle, wszTitle);
176 /* Add the item to the list */
177 memset(&item, 0, sizeof(LV_ITEMW));
178 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
179 ImageList_AddIcon(hImageListLarge, hIcon);
180 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
181 item.pszText = LPSTR_TEXTCALLBACKW;
182 item.iItem = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
183 item.lParam = (LPARAM)pAPLI;
184 SendMessageW(hApplicationPageListCtrl, LVM_INSERTITEMW, 0, (LPARAM) &item);
188 /* Check to see if we need to remove any items from the list */
189 for (i=SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0)-1; i>=0; i--)
191 memset(&item, 0, sizeof(LV_ITEMW));
192 item.mask = LVIF_IMAGE|LVIF_PARAM;
193 item.iItem = i;
194 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
196 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
197 if (!IsWindow(pAPLI->hWnd)||
198 (lstrlenW(pAPLI->wszTitle) <= 0) ||
199 !IsWindowVisible(pAPLI->hWnd) ||
200 (GetParent(pAPLI->hWnd) != NULL) ||
201 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
202 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
204 ImageList_Remove(hImageListLarge, item.iItem);
205 ImageList_Remove(hImageListSmall, item.iItem);
207 SendMessageW(hApplicationPageListCtrl, LVM_DELETEITEM, item.iItem, 0);
208 HeapFree(GetProcessHeap(), 0, pAPLI);
209 bItemRemoved = TRUE;
214 * If an item was removed from the list then
215 * we need to resync all the items with the
216 * image list
218 if (bItemRemoved)
220 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
221 for (i=0; i<count; i++)
223 memset(&item, 0, sizeof(LV_ITEMW));
224 item.mask = LVIF_IMAGE;
225 item.iItem = i;
226 item.iImage = i;
227 SendMessageW(hApplicationPageListCtrl, LVM_SETITEMW, 0, (LPARAM) &item);
231 ApplicationPageUpdate();
234 static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
236 HICON hIcon;
237 WCHAR wszText[256];
238 BOOL bLargeIcon = TaskManagerSettings.View_LargeIcons;
240 /* Skip our window */
241 if (hWnd == hMainWnd)
242 return TRUE;
244 /* Check and see if this is a top-level app window */
245 if (!GetWindowTextW(hWnd, wszText, ARRAY_SIZE(wszText)) || !IsWindowVisible(hWnd) ||
246 (GetParent(hWnd) != NULL) || (GetWindow(hWnd, GW_OWNER) != NULL) ||
247 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
249 return TRUE; /* Skip this window */
252 /* Get the icon for this window */
253 hIcon = NULL;
254 SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
256 if (!hIcon)
258 hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM);
259 if (!hIcon) hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON);
260 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)&hIcon);
261 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
264 if (!hIcon)
265 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
267 AddOrUpdateHwnd(hWnd, wszText, hIcon, IsHungAppWindow(hWnd));
269 return TRUE;
272 static DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
274 /* Create the event */
275 hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
277 /* If we couldn't create the event then exit the thread */
278 if (!hApplicationPageEvent)
279 return 0;
281 while (1)
283 DWORD dwWaitVal;
285 /* Wait on the event */
286 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
288 /* If the wait failed then the event object must have been */
289 /* closed and the task manager is exiting so exit this thread */
290 if (dwWaitVal == WAIT_FAILED)
291 return 0;
293 if (dwWaitVal == WAIT_OBJECT_0)
295 /* Reset our event */
296 ResetEvent(hApplicationPageEvent);
299 * FIXME:
301 * Should this be EnumDesktopWindows() instead?
303 EnumWindows(EnumWindowsProc, 0);
308 static void ApplicationPageShowContextMenu1(void)
310 HMENU hMenu;
311 HMENU hSubMenu;
312 POINT pt;
314 GetCursorPos(&pt);
316 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
317 hSubMenu = GetSubMenu(hMenu, 0);
319 if (TaskManagerSettings.View_LargeIcons)
320 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
321 else if (TaskManagerSettings.View_SmallIcons)
322 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
323 else
324 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
326 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
328 DestroyMenu(hMenu);
331 static void ApplicationPageShowContextMenu2(void)
333 HMENU hMenu;
334 HMENU hSubMenu;
335 UINT count;
336 POINT pt;
338 GetCursorPos(&pt);
340 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
341 hSubMenu = GetSubMenu(hMenu, 0);
343 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
344 if (count == 1)
346 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
347 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
348 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
349 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
350 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
351 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
353 else if (count > 1)
355 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
356 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
357 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
358 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
359 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
360 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
362 else
364 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
365 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
366 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
367 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
368 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
369 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
372 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
374 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
376 DestroyMenu(hMenu);
379 static int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
381 LPAPPLICATION_PAGE_LIST_ITEM Param1;
382 LPAPPLICATION_PAGE_LIST_ITEM Param2;
384 if (bSortAscending) {
385 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
386 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
387 } else {
388 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
389 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
391 return lstrcmpW(Param1->wszTitle, Param2->wszTitle);
394 static void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
396 LPNMHDR pnmh;
397 LV_DISPINFOW* pnmdi;
398 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
399 WCHAR wszNotResponding[255];
400 WCHAR wszRunning[255];
402 LoadStringW(hInst, IDS_APPLICATION_NOT_RESPONDING, wszNotResponding, ARRAY_SIZE(wszNotResponding));
403 LoadStringW(hInst, IDS_APPLICATION_RUNNING, wszRunning, ARRAY_SIZE(wszRunning));
405 pnmh = (LPNMHDR) lParam;
406 pnmdi = (LV_DISPINFOW*) lParam;
408 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
409 switch (pnmh->code) {
410 case LVN_ITEMCHANGED:
411 ApplicationPageUpdate();
412 break;
414 case LVN_GETDISPINFOW:
415 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
417 /* Update the item text */
418 if (pnmdi->item.iSubItem == 0)
420 lstrcpynW(pnmdi->item.pszText, pAPLI->wszTitle, pnmdi->item.cchTextMax);
423 /* Update the item status */
424 else if (pnmdi->item.iSubItem == 1)
426 if (pAPLI->bHung)
427 lstrcpynW(pnmdi->item.pszText, wszNotResponding, pnmdi->item.cchTextMax);
428 else
429 lstrcpynW(pnmdi->item.pszText, wszRunning, pnmdi->item.cchTextMax);
432 break;
434 case NM_RCLICK:
436 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
438 ApplicationPageShowContextMenu1();
440 else
442 ApplicationPageShowContextMenu2();
445 break;
447 case NM_DBLCLK:
449 ApplicationPage_OnSwitchTo();
451 break;
454 else if (pnmh->hwndFrom == (HWND)SendMessageW(hApplicationPageListCtrl, LVM_GETHEADER, 0, 0))
456 switch (pnmh->code)
458 case NM_RCLICK:
460 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
462 ApplicationPageShowContextMenu1();
464 else
466 ApplicationPageShowContextMenu2();
469 break;
471 case HDN_ITEMCLICKW:
473 SendMessageW(hApplicationPageListCtrl, LVM_SORTITEMS, 0, (LPARAM) ApplicationPageCompareFunc);
474 bSortAscending = !bSortAscending;
476 break;
482 void RefreshApplicationPage(void)
484 /* Signal the event so that our refresh thread */
485 /* will wake up and refresh the application page */
486 SetEvent(hApplicationPageEvent);
489 static void UpdateApplicationListControlViewSetting(void)
491 DWORD dwStyle = GetWindowLongW(hApplicationPageListCtrl, GWL_STYLE);
493 dwStyle &= ~LVS_REPORT;
494 dwStyle &= ~LVS_ICON;
495 dwStyle &= ~LVS_LIST;
496 dwStyle &= ~LVS_SMALLICON;
498 if (TaskManagerSettings.View_LargeIcons)
499 dwStyle |= LVS_ICON;
500 else if (TaskManagerSettings.View_SmallIcons)
501 dwStyle |= LVS_SMALLICON;
502 else
503 dwStyle |= LVS_REPORT;
505 SetWindowLongW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
507 RefreshApplicationPage();
510 void ApplicationPage_OnViewLargeIcons(void)
512 HMENU hMenu;
513 HMENU hViewMenu;
515 hMenu = GetMenu(hMainWnd);
516 hViewMenu = GetSubMenu(hMenu, 2);
518 TaskManagerSettings.View_LargeIcons = TRUE;
519 TaskManagerSettings.View_SmallIcons = FALSE;
520 TaskManagerSettings.View_Details = FALSE;
521 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
523 UpdateApplicationListControlViewSetting();
526 void ApplicationPage_OnViewSmallIcons(void)
528 HMENU hMenu;
529 HMENU hViewMenu;
531 hMenu = GetMenu(hMainWnd);
532 hViewMenu = GetSubMenu(hMenu, 2);
534 TaskManagerSettings.View_LargeIcons = FALSE;
535 TaskManagerSettings.View_SmallIcons = TRUE;
536 TaskManagerSettings.View_Details = FALSE;
537 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
539 UpdateApplicationListControlViewSetting();
542 void ApplicationPage_OnViewDetails(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 = FALSE;
552 TaskManagerSettings.View_Details = TRUE;
553 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
555 UpdateApplicationListControlViewSetting();
558 void ApplicationPage_OnWindowsTileHorizontally(void)
560 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
561 LV_ITEMW item;
562 int i, count;
563 HWND* hWndArray;
564 int nWndCount;
566 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
567 hWndArray = HeapAlloc(GetProcessHeap(), 0,
568 sizeof(HWND) * count);
569 nWndCount = 0;
571 for (i=0; i<count; i++) {
572 memset(&item, 0, sizeof(LV_ITEMW));
573 item.mask = LVIF_STATE|LVIF_PARAM;
574 item.iItem = i;
575 item.stateMask = (UINT)-1;
576 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
578 if (item.state & LVIS_SELECTED) {
579 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
581 if (pAPLI) {
582 hWndArray[nWndCount] = pAPLI->hWnd;
583 nWndCount++;
587 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
588 HeapFree(GetProcessHeap(), 0, hWndArray);
591 void ApplicationPage_OnWindowsTileVertically(void)
593 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
594 LV_ITEMW item;
595 int i, count;
596 HWND* hWndArray;
597 int nWndCount;
599 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
600 hWndArray = HeapAlloc(GetProcessHeap(), 0,
601 sizeof(HWND) * count);
602 nWndCount = 0;
604 for (i=0; i<count; i++) {
605 memset(&item, 0, sizeof(LV_ITEMW));
606 item.mask = LVIF_STATE|LVIF_PARAM;
607 item.iItem = i;
608 item.stateMask = (UINT)-1;
609 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
611 if (item.state & LVIS_SELECTED) {
612 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
613 if (pAPLI) {
614 hWndArray[nWndCount] = pAPLI->hWnd;
615 nWndCount++;
620 TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
621 HeapFree(GetProcessHeap(), 0, hWndArray);
624 void ApplicationPage_OnWindowsMinimize(void)
626 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
627 LV_ITEMW item;
628 int i, count;
630 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
631 for (i=0; i<count; i++) {
632 memset(&item, 0, sizeof(LV_ITEMW));
633 item.mask = LVIF_STATE|LVIF_PARAM;
634 item.iItem = i;
635 item.stateMask = (UINT)-1;
636 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
637 if (item.state & LVIS_SELECTED) {
638 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
639 if (pAPLI) {
640 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
646 void ApplicationPage_OnWindowsMaximize(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_MAXIMIZE);
668 void ApplicationPage_OnWindowsCascade(void)
670 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
671 LV_ITEMW item;
672 int i, count;
673 HWND* hWndArray;
674 int nWndCount;
676 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
677 hWndArray = HeapAlloc(GetProcessHeap(), 0,
678 sizeof(HWND) * count);
679 nWndCount = 0;
681 for (i=0; i<count; i++) {
682 memset(&item, 0, sizeof(LV_ITEMW));
683 item.mask = LVIF_STATE|LVIF_PARAM;
684 item.iItem = i;
685 item.stateMask = (UINT)-1;
686 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
687 if (item.state & LVIS_SELECTED) {
688 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
689 if (pAPLI) {
690 hWndArray[nWndCount] = pAPLI->hWnd;
691 nWndCount++;
695 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
696 HeapFree(GetProcessHeap(), 0, hWndArray);
699 void ApplicationPage_OnWindowsBringToFront(void)
701 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
702 LV_ITEMW item;
703 int i, count;
705 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
706 for (i=0; i<count; i++) {
707 memset(&item, 0, sizeof(LV_ITEMW));
708 item.mask = LVIF_STATE|LVIF_PARAM;
709 item.iItem = i;
710 item.stateMask = (UINT)-1;
711 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
712 if (item.state & LVIS_SELECTED) {
713 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
714 break;
717 if (pAPLI) {
718 if (IsIconic(pAPLI->hWnd))
719 ShowWindow(pAPLI->hWnd, SW_RESTORE);
720 BringWindowToTop(pAPLI->hWnd);
724 void ApplicationPage_OnSwitchTo(void)
726 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
727 LV_ITEMW item;
728 int i, count;
730 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
731 for (i=0; i<count; i++) {
732 memset(&item, 0, sizeof(LV_ITEMW));
733 item.mask = LVIF_STATE|LVIF_PARAM;
734 item.iItem = i;
735 item.stateMask = (UINT)-1;
736 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
738 if (item.state & LVIS_SELECTED) {
739 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
740 break;
743 if (pAPLI) {
744 SwitchToThisWindow(pAPLI->hWnd, TRUE);
745 if (TaskManagerSettings.MinimizeOnUse)
746 ShowWindow(hMainWnd, SW_MINIMIZE);
750 void ApplicationPage_OnEndTask(void)
752 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
753 LV_ITEMW item;
754 int i, count;
756 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
757 for (i=0; i<count; i++) {
758 memset(&item, 0, sizeof(LV_ITEMW));
759 item.mask = LVIF_STATE|LVIF_PARAM;
760 item.iItem = i;
761 item.stateMask = (UINT)-1;
762 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
763 if (item.state & LVIS_SELECTED) {
764 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
765 if (pAPLI) {
766 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
772 void ApplicationPage_OnGotoProcess(void)
774 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
775 LV_ITEMW item;
776 int i, count;
777 /* NMHDR nmhdr; */
779 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
780 for (i=0; i<count; i++) {
781 memset(&item, 0, sizeof(LV_ITEMW));
782 item.mask = LVIF_STATE|LVIF_PARAM;
783 item.iItem = i;
784 item.stateMask = (UINT)-1;
785 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
786 if (item.state & LVIS_SELECTED) {
787 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
788 break;
791 if (pAPLI) {
792 DWORD dwProcessId;
794 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
796 * Switch to the process tab
798 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 1, 0);
800 * FIXME: Select the process item in the list
805 INT_PTR CALLBACK
806 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
808 RECT rc;
809 int nXDifference;
810 int nYDifference;
811 int cx, cy;
812 LVCOLUMNW column;
814 WCHAR wszTask[255];
815 WCHAR wszStatus[255];
817 LoadStringW(hInst, IDS_APPLICATION_TASK, wszTask, ARRAY_SIZE(wszTask));
818 LoadStringW(hInst, IDS_APPLICATION_STATUS, wszStatus, ARRAY_SIZE(wszStatus));
820 switch (message) {
821 case WM_INITDIALOG:
823 /* Save the width and height */
824 GetClientRect(hDlg, &rc);
825 nApplicationPageWidth = rc.right;
826 nApplicationPageHeight = rc.bottom;
828 /* Update window position */
829 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
831 /* Get handles to the controls */
832 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
833 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
834 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
835 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
837 /* Initialize the application page's controls */
838 column.mask = LVCF_TEXT|LVCF_WIDTH;
839 column.pszText = wszTask;
840 column.cx = 250;
841 /* Add the "Task" column */
842 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM) &column);
843 column.mask = LVCF_TEXT|LVCF_WIDTH;
844 column.pszText = wszStatus;
845 column.cx = 95;
846 /* Add the "Status" column */
847 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
849 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_SMALL,
850 (LPARAM) ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1));
851 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_NORMAL,
852 (LPARAM) ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1));
854 UpdateApplicationListControlViewSetting();
856 /* Start our refresh thread */
857 CloseHandle( CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL));
859 return TRUE;
861 case WM_DESTROY:
862 /* Close the event handle, this will make the */
863 /* refresh thread exit when the wait fails */
864 CloseHandle(hApplicationPageEvent);
865 break;
867 case WM_COMMAND:
869 /* Handle the button clicks */
870 switch (LOWORD(wParam))
872 case IDC_ENDTASK:
873 ApplicationPage_OnEndTask();
874 break;
875 case IDC_SWITCHTO:
876 ApplicationPage_OnSwitchTo();
877 break;
878 case IDC_NEWTASK:
879 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
880 break;
883 break;
885 case WM_SIZE:
886 if (wParam == SIZE_MINIMIZED)
887 return 0;
889 cx = LOWORD(lParam);
890 cy = HIWORD(lParam);
891 nXDifference = cx - nApplicationPageWidth;
892 nYDifference = cy - nApplicationPageHeight;
893 nApplicationPageWidth = cx;
894 nApplicationPageHeight = cy;
896 /* Reposition the application page's controls */
897 GetWindowRect(hApplicationPageListCtrl, &rc);
898 cx = (rc.right - rc.left) + nXDifference;
899 cy = (rc.bottom - rc.top) + nYDifference;
900 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
901 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
903 GetClientRect(hApplicationPageEndTaskButton, &rc);
904 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
905 cx = rc.left + nXDifference;
906 cy = rc.top + nYDifference;
907 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
908 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
910 GetClientRect(hApplicationPageSwitchToButton, &rc);
911 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
912 cx = rc.left + nXDifference;
913 cy = rc.top + nYDifference;
914 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
915 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
917 GetClientRect(hApplicationPageNewTaskButton, &rc);
918 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
919 cx = rc.left + nXDifference;
920 cy = rc.top + nYDifference;
921 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
922 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
924 break;
926 case WM_NOTIFY:
927 ApplicationPageOnNotify(wParam, lParam);
928 break;
932 return 0;