push 8742e928a3d078c1d2cecb5ceee0ffde3118cbb7
[wine/hacks.git] / programs / taskmgr / applpage.c
blobf6fbf167e276387b01c0f65d09b0daad53d3d4a8
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 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
25 #include <windows.h>
26 #include <commctrl.h>
27 #include <stdlib.h>
28 #include <malloc.h>
29 #include <memory.h>
30 #include <stdio.h>
32 #include "wine/unicode.h"
33 #include "taskmgr.h"
35 typedef struct
37 HWND hWnd;
38 WCHAR wszTitle[256];
39 HICON hIcon;
40 BOOL bHung;
41 } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM;
43 HWND hApplicationPage; /* Application List Property Page */
44 HWND hApplicationPageListCtrl; /* Application ListCtrl Window */
45 HWND hApplicationPageEndTaskButton; /* Application End Task button */
46 HWND hApplicationPageSwitchToButton; /* Application Switch To button */
47 HWND hApplicationPageNewTaskButton; /* Application New Task button */
48 static int nApplicationPageWidth;
49 static int nApplicationPageHeight;
50 static HANDLE hApplicationPageEvent = NULL; /* When this event becomes signaled then we refresh the app list */
51 static BOOL bSortAscending = TRUE;
53 static const WCHAR wszUser32[] = {'U','S','E','R','3','2','.','D','L','L',0};
54 #if 0
55 void SwitchToThisWindow (
56 HWND hWnd, /* Handle to the window that should be activated */
57 BOOL bRestore /* Restore the window if it is minimized */
59 #endif
61 static void ApplicationPageUpdate(void)
63 /* Enable or disable the "End Task" & "Switch To" buttons */
64 if (ListView_GetSelectedCount(hApplicationPageListCtrl))
66 EnableWindow(hApplicationPageEndTaskButton, TRUE);
67 EnableWindow(hApplicationPageSwitchToButton, TRUE);
69 else
71 EnableWindow(hApplicationPageEndTaskButton, FALSE);
72 EnableWindow(hApplicationPageSwitchToButton, FALSE);
75 /* If we are on the applications tab, then the windows menu will */
76 /* be present on the menu bar so enable & disable the menu items */
77 if (TabCtrl_GetCurSel(hTabWnd) == 0)
79 HMENU hMenu;
80 HMENU hWindowsMenu;
82 hMenu = GetMenu(hMainWnd);
83 hWindowsMenu = GetSubMenu(hMenu, 3);
85 /* Only one item selected */
86 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 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 (ListView_GetSelectedCount(hApplicationPageListCtrl) > 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;
125 BOOL bAlreadyInList = FALSE;
126 BOOL bItemRemoved = FALSE;
128 memset(&item, 0, sizeof(LV_ITEMW));
130 /* Get the image lists */
131 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL);
132 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL);
134 /* Check to see if it's already in our list */
135 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
137 memset(&item, 0, sizeof(LV_ITEMW));
138 item.mask = LVIF_IMAGE|LVIF_PARAM;
139 item.iItem = i;
140 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
142 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
143 if (pAPLI->hWnd == hWnd)
145 bAlreadyInList = TRUE;
146 break;
150 /* If it is already in the list then update it if necessary */
151 if (bAlreadyInList)
153 /* Check to see if anything needs updating */
154 if ((pAPLI->hIcon != hIcon) ||
155 (strcmpW(pAPLI->wszTitle, wszTitle) != 0) ||
156 (pAPLI->bHung != bHung))
158 /* Update the structure */
159 pAPLI->hIcon = hIcon;
160 pAPLI->bHung = bHung;
161 strcpyW(pAPLI->wszTitle, wszTitle);
163 /* Update the image list */
164 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
165 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
167 /* Update the list view */
168 SendMessageW(hApplicationPageListCtrl, LVM_REDRAWITEMS, 0, ListView_GetItemCount(hApplicationPageListCtrl));
169 /* UpdateWindow(hApplicationPageListCtrl); */
170 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
173 /* It is not already in the list so add it */
174 else
176 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)malloc(sizeof(APPLICATION_PAGE_LIST_ITEM));
178 pAPLI->hWnd = hWnd;
179 pAPLI->hIcon = hIcon;
180 pAPLI->bHung = bHung;
181 strcpyW(pAPLI->wszTitle, wszTitle);
183 /* Add the item to the list */
184 memset(&item, 0, sizeof(LV_ITEMW));
185 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
186 ImageList_AddIcon(hImageListLarge, hIcon);
187 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
188 item.pszText = LPSTR_TEXTCALLBACKW;
189 item.iItem = ListView_GetItemCount(hApplicationPageListCtrl);
190 item.lParam = (LPARAM)pAPLI;
191 SendMessageW(hApplicationPageListCtrl, LVM_INSERTITEMW, 0, (LPARAM) &item);
195 /* Check to see if we need to remove any items from the list */
196 for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--)
198 memset(&item, 0, sizeof(LV_ITEMW));
199 item.mask = LVIF_IMAGE|LVIF_PARAM;
200 item.iItem = i;
201 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
203 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
204 if (!IsWindow(pAPLI->hWnd)||
205 (strlenW(pAPLI->wszTitle) <= 0) ||
206 !IsWindowVisible(pAPLI->hWnd) ||
207 (GetParent(pAPLI->hWnd) != NULL) ||
208 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
209 (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
211 ImageList_Remove(hImageListLarge, item.iItem);
212 ImageList_Remove(hImageListSmall, item.iItem);
214 SendMessage(hApplicationPageListCtrl, LVM_DELETEITEM, item.iItem, 0);
215 free(pAPLI);
216 bItemRemoved = TRUE;
221 * If an item was removed from the list then
222 * we need to resync all the items with the
223 * image list
225 if (bItemRemoved)
227 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
229 memset(&item, 0, sizeof(LV_ITEMW));
230 item.mask = LVIF_IMAGE;
231 item.iItem = i;
232 item.iImage = i;
233 SendMessageW(hApplicationPageListCtrl, LVM_SETITEMW, 0, (LPARAM) &item);
237 ApplicationPageUpdate();
240 static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
242 HICON hIcon;
243 WCHAR wszText[256];
244 BOOL bLargeIcon;
245 BOOL bHung = FALSE;
246 typedef int (__stdcall *IsHungAppWindowProc)(HWND);
247 IsHungAppWindowProc IsHungAppWindow;
250 /* Skip our window */
251 if (hWnd == hMainWnd)
252 return TRUE;
254 bLargeIcon = TaskManagerSettings.View_LargeIcons ? TRUE : FALSE;
256 /* Check and see if this is a top-level app window */
257 if (!GetWindowTextW(hWnd, wszText, sizeof(wszText)/sizeof(WCHAR)) ||
258 !IsWindowVisible(hWnd) ||
259 (GetParent(hWnd) != NULL) ||
260 (GetWindow(hWnd, GW_OWNER) != NULL) ||
261 (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
263 return TRUE; /* Skip this window */
266 /* Get the icon for this window */
267 hIcon = NULL;
268 SendMessageTimeout(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
270 if (!hIcon)
272 hIcon = (HICON)GetClassLongPtr(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM);
273 if (!hIcon) hIcon = (HICON)GetClassLongPtr(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON);
274 if (!hIcon) SendMessageTimeout(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)&hIcon);
275 if (!hIcon) SendMessageTimeout(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
278 if (!hIcon)
279 hIcon = LoadIcon(hInst, bLargeIcon ? MAKEINTRESOURCE(IDI_WINDOW) : MAKEINTRESOURCE(IDI_WINDOWSM));
281 bHung = FALSE;
283 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(wszUser32), "IsHungAppWindow");
285 if (IsHungAppWindow)
286 bHung = IsHungAppWindow(hWnd);
288 AddOrUpdateHwnd(hWnd, wszText, hIcon, bHung);
290 return TRUE;
293 static DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
295 /* Create the event */
296 hApplicationPageEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
298 /* If we couldn't create the event then exit the thread */
299 if (!hApplicationPageEvent)
300 return 0;
302 while (1)
304 DWORD dwWaitVal;
306 /* Wait on the event */
307 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
309 /* If the wait failed then the event object must have been */
310 /* closed and the task manager is exiting so exit this thread */
311 if (dwWaitVal == WAIT_FAILED)
312 return 0;
314 if (dwWaitVal == WAIT_OBJECT_0)
316 /* Reset our event */
317 ResetEvent(hApplicationPageEvent);
320 * FIXME:
322 * Should this be EnumDesktopWindows() instead?
324 EnumWindows(EnumWindowsProc, 0);
329 static void ApplicationPageShowContextMenu1(void)
331 HMENU hMenu;
332 HMENU hSubMenu;
333 POINT pt;
335 GetCursorPos(&pt);
337 hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_APPLICATION_PAGE_CONTEXT1));
338 hSubMenu = GetSubMenu(hMenu, 0);
340 if (TaskManagerSettings.View_LargeIcons)
341 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
342 else if (TaskManagerSettings.View_SmallIcons)
343 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
344 else
345 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
347 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
349 DestroyMenu(hMenu);
352 static void ApplicationPageShowContextMenu2(void)
354 HMENU hMenu;
355 HMENU hSubMenu;
356 POINT pt;
358 GetCursorPos(&pt);
360 hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_APPLICATION_PAGE_CONTEXT2));
361 hSubMenu = GetSubMenu(hMenu, 0);
363 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1)
365 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
366 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
367 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
368 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
369 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
370 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
372 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1)
374 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
375 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
376 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
377 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
378 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
379 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
381 else
383 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
384 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
385 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
386 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
387 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
388 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
391 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
393 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
395 DestroyMenu(hMenu);
398 static int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
400 LPAPPLICATION_PAGE_LIST_ITEM Param1;
401 LPAPPLICATION_PAGE_LIST_ITEM Param2;
403 if (bSortAscending) {
404 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
405 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
406 } else {
407 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
408 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
410 return strcmpW(Param1->wszTitle, Param2->wszTitle);
413 static void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
415 int idctrl;
416 LPNMHDR pnmh;
417 LPNM_LISTVIEW pnmv;
418 LV_DISPINFOW* pnmdi;
419 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
421 static const WCHAR wszNotResponding[] = {'N','o','t',' ','R','e','s','p','o','n','d','i','n','g',0};
422 static const WCHAR wszRunning[] = {'R','u','n','n','i','n','g',0};
425 idctrl = (int) wParam;
426 pnmh = (LPNMHDR) lParam;
427 pnmv = (LPNM_LISTVIEW) 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 (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
460 ApplicationPageShowContextMenu1();
462 else
464 ApplicationPageShowContextMenu2();
467 break;
469 case NM_DBLCLK:
471 ApplicationPage_OnSwitchTo();
473 break;
476 else if (pnmh->hwndFrom == ListView_GetHeader(hApplicationPageListCtrl))
478 switch (pnmh->code)
480 case NM_RCLICK:
482 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
484 ApplicationPageShowContextMenu1();
486 else
488 ApplicationPageShowContextMenu2();
491 break;
493 case HDN_ITEMCLICK:
495 SendMessageW(hApplicationPageListCtrl, LVM_SORTITEMS, 0, (LPARAM) ApplicationPageCompareFunc);
496 bSortAscending = !bSortAscending;
498 break;
504 INT_PTR CALLBACK
505 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
507 RECT rc;
508 int nXDifference;
509 int nYDifference;
510 int cx, cy;
511 LVCOLUMNW column;
513 static const WCHAR wszTasks[] = {'T','a','s','k','s',0};
514 static WCHAR wszTask[] = {'T','a','s','k',0};
515 static WCHAR wszStatus[] = {'S','t','a','t','u','s',0};
517 switch (message) {
518 case WM_INITDIALOG:
520 /* Save the width and height */
521 GetClientRect(hDlg, &rc);
522 nApplicationPageWidth = rc.right;
523 nApplicationPageHeight = rc.bottom;
525 /* Update window position */
526 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
528 /* Get handles to the controls */
529 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
530 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
531 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
532 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
534 SetWindowTextW(hApplicationPageListCtrl, wszTasks);
536 /* Initialize the application page's controls */
537 column.mask = LVCF_TEXT|LVCF_WIDTH;
538 column.pszText = wszTask;
539 column.cx = 250;
540 /* Add the "Task" column */
541 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM) &column);
542 column.mask = LVCF_TEXT|LVCF_WIDTH;
543 column.pszText = wszStatus;
544 column.cx = 95;
545 /* Add the "Status" column */
546 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
548 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_SMALL,
549 (LPARAM) ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1));
550 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_NORMAL,
551 (LPARAM) ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1));
553 UpdateApplicationListControlViewSetting();
555 /* Start our refresh thread */
556 CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL);
558 return TRUE;
560 case WM_DESTROY:
561 /* Close the event handle, this will make the */
562 /* refresh thread exit when the wait fails */
563 CloseHandle(hApplicationPageEvent);
564 break;
566 case WM_COMMAND:
568 /* Handle the button clicks */
569 switch (LOWORD(wParam))
571 case IDC_ENDTASK:
572 ApplicationPage_OnEndTask();
573 break;
574 case IDC_SWITCHTO:
575 ApplicationPage_OnSwitchTo();
576 break;
577 case IDC_NEWTASK:
578 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
579 break;
582 break;
584 case WM_SIZE:
585 if (wParam == SIZE_MINIMIZED)
586 return 0;
588 cx = LOWORD(lParam);
589 cy = HIWORD(lParam);
590 nXDifference = cx - nApplicationPageWidth;
591 nYDifference = cy - nApplicationPageHeight;
592 nApplicationPageWidth = cx;
593 nApplicationPageHeight = cy;
595 /* Reposition the application page's controls */
596 GetWindowRect(hApplicationPageListCtrl, &rc);
597 cx = (rc.right - rc.left) + nXDifference;
598 cy = (rc.bottom - rc.top) + nYDifference;
599 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
600 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
602 GetClientRect(hApplicationPageEndTaskButton, &rc);
603 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
604 cx = rc.left + nXDifference;
605 cy = rc.top + nYDifference;
606 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
607 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
609 GetClientRect(hApplicationPageSwitchToButton, &rc);
610 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
611 cx = rc.left + nXDifference;
612 cy = rc.top + nYDifference;
613 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
614 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
616 GetClientRect(hApplicationPageNewTaskButton, &rc);
617 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
618 cx = rc.left + nXDifference;
619 cy = rc.top + nYDifference;
620 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
621 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
623 break;
625 case WM_NOTIFY:
626 ApplicationPageOnNotify(wParam, lParam);
627 break;
631 return 0;
634 void RefreshApplicationPage(void)
636 /* Signal the event so that our refresh thread */
637 /* will wake up and refresh the application page */
638 SetEvent(hApplicationPageEvent);
641 void UpdateApplicationListControlViewSetting(void)
643 DWORD dwStyle = GetWindowLong(hApplicationPageListCtrl, GWL_STYLE);
645 dwStyle &= ~LVS_REPORT;
646 dwStyle &= ~LVS_ICON;
647 dwStyle &= ~LVS_LIST;
648 dwStyle &= ~LVS_SMALLICON;
650 if (TaskManagerSettings.View_LargeIcons)
651 dwStyle |= LVS_ICON;
652 else if (TaskManagerSettings.View_SmallIcons)
653 dwStyle |= LVS_SMALLICON;
654 else
655 dwStyle |= LVS_REPORT;
657 SetWindowLong(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
659 RefreshApplicationPage();
662 void ApplicationPage_OnViewLargeIcons(void)
664 HMENU hMenu;
665 HMENU hViewMenu;
667 hMenu = GetMenu(hMainWnd);
668 hViewMenu = GetSubMenu(hMenu, 2);
670 TaskManagerSettings.View_LargeIcons = TRUE;
671 TaskManagerSettings.View_SmallIcons = FALSE;
672 TaskManagerSettings.View_Details = FALSE;
673 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
675 UpdateApplicationListControlViewSetting();
678 void ApplicationPage_OnViewSmallIcons(void)
680 HMENU hMenu;
681 HMENU hViewMenu;
683 hMenu = GetMenu(hMainWnd);
684 hViewMenu = GetSubMenu(hMenu, 2);
686 TaskManagerSettings.View_LargeIcons = FALSE;
687 TaskManagerSettings.View_SmallIcons = TRUE;
688 TaskManagerSettings.View_Details = FALSE;
689 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
691 UpdateApplicationListControlViewSetting();
694 void ApplicationPage_OnViewDetails(void)
696 HMENU hMenu;
697 HMENU hViewMenu;
699 hMenu = GetMenu(hMainWnd);
700 hViewMenu = GetSubMenu(hMenu, 2);
702 TaskManagerSettings.View_LargeIcons = FALSE;
703 TaskManagerSettings.View_SmallIcons = FALSE;
704 TaskManagerSettings.View_Details = TRUE;
705 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
707 UpdateApplicationListControlViewSetting();
710 void ApplicationPage_OnWindowsTileHorizontally(void)
712 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
713 LV_ITEMW item;
714 int i;
715 HWND* hWndArray;
716 int nWndCount;
718 hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
719 nWndCount = 0;
721 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
722 memset(&item, 0, sizeof(LV_ITEMW));
723 item.mask = LVIF_STATE|LVIF_PARAM;
724 item.iItem = i;
725 item.stateMask = (UINT)-1;
726 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
728 if (item.state & LVIS_SELECTED) {
729 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
731 if (pAPLI) {
732 hWndArray[nWndCount] = pAPLI->hWnd;
733 nWndCount++;
737 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
738 free(hWndArray);
741 void ApplicationPage_OnWindowsTileVertically(void)
743 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
744 LV_ITEMW item;
745 int i;
746 HWND* hWndArray;
747 int nWndCount;
749 hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
750 nWndCount = 0;
752 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
753 memset(&item, 0, sizeof(LV_ITEMW));
754 item.mask = LVIF_STATE|LVIF_PARAM;
755 item.iItem = i;
756 item.stateMask = (UINT)-1;
757 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
759 if (item.state & LVIS_SELECTED) {
760 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
761 if (pAPLI) {
762 hWndArray[nWndCount] = pAPLI->hWnd;
763 nWndCount++;
768 TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
769 free(hWndArray);
772 void ApplicationPage_OnWindowsMinimize(void)
774 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
775 LV_ITEMW item;
776 int i;
778 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
779 memset(&item, 0, sizeof(LV_ITEMW));
780 item.mask = LVIF_STATE|LVIF_PARAM;
781 item.iItem = i;
782 item.stateMask = (UINT)-1;
783 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
784 if (item.state & LVIS_SELECTED) {
785 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
786 if (pAPLI) {
787 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
793 void ApplicationPage_OnWindowsMaximize(void)
795 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
796 LV_ITEMW item;
797 int i;
799 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
800 memset(&item, 0, sizeof(LV_ITEMW));
801 item.mask = LVIF_STATE|LVIF_PARAM;
802 item.iItem = i;
803 item.stateMask = (UINT)-1;
804 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
805 if (item.state & LVIS_SELECTED) {
806 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
807 if (pAPLI) {
808 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
814 void ApplicationPage_OnWindowsCascade(void)
816 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
817 LV_ITEMW item;
818 int i;
819 HWND* hWndArray;
820 int nWndCount;
822 hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
823 nWndCount = 0;
825 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
826 memset(&item, 0, sizeof(LV_ITEMW));
827 item.mask = LVIF_STATE|LVIF_PARAM;
828 item.iItem = i;
829 item.stateMask = (UINT)-1;
830 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
831 if (item.state & LVIS_SELECTED) {
832 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
833 if (pAPLI) {
834 hWndArray[nWndCount] = pAPLI->hWnd;
835 nWndCount++;
839 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
840 free(hWndArray);
843 void ApplicationPage_OnWindowsBringToFront(void)
845 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
846 LV_ITEMW item;
847 int i;
849 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
850 memset(&item, 0, sizeof(LV_ITEMW));
851 item.mask = LVIF_STATE|LVIF_PARAM;
852 item.iItem = i;
853 item.stateMask = (UINT)-1;
854 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
855 if (item.state & LVIS_SELECTED) {
856 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
857 break;
860 if (pAPLI) {
861 if (IsIconic(pAPLI->hWnd))
862 ShowWindow(pAPLI->hWnd, SW_RESTORE);
863 BringWindowToTop(pAPLI->hWnd);
867 void ApplicationPage_OnSwitchTo(void)
869 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
870 LV_ITEMW item;
871 int i;
873 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
874 memset(&item, 0, sizeof(LV_ITEMW));
875 item.mask = LVIF_STATE|LVIF_PARAM;
876 item.iItem = i;
877 item.stateMask = (UINT)-1;
878 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
880 if (item.state & LVIS_SELECTED) {
881 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
882 break;
885 if (pAPLI) {
886 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
887 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
889 HMODULE hUser32 = GetModuleHandleW(wszUser32);
890 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
891 if (SwitchToThisWindow) {
892 SwitchToThisWindow(pAPLI->hWnd, TRUE);
893 } else {
894 if (IsIconic(pAPLI->hWnd))
895 ShowWindow(pAPLI->hWnd, SW_RESTORE);
896 BringWindowToTop(pAPLI->hWnd);
897 SetForegroundWindow(pAPLI->hWnd);
899 if (TaskManagerSettings.MinimizeOnUse)
900 ShowWindow(hMainWnd, SW_MINIMIZE);
904 void ApplicationPage_OnEndTask(void)
906 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
907 LV_ITEMW item;
908 int i;
910 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
911 memset(&item, 0, sizeof(LV_ITEMW));
912 item.mask = LVIF_STATE|LVIF_PARAM;
913 item.iItem = i;
914 item.stateMask = (UINT)-1;
915 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
916 if (item.state & LVIS_SELECTED) {
917 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
918 if (pAPLI) {
919 PostMessage(pAPLI->hWnd, WM_CLOSE, 0, 0);
925 void ApplicationPage_OnGotoProcess(void)
927 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
928 LV_ITEMW item;
929 int i;
930 /* NMHDR nmhdr; */
932 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
933 memset(&item, 0, sizeof(LV_ITEMW));
934 item.mask = LVIF_STATE|LVIF_PARAM;
935 item.iItem = i;
936 item.stateMask = (UINT)-1;
937 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
938 if (item.state & LVIS_SELECTED) {
939 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
940 break;
943 if (pAPLI) {
944 DWORD dwProcessId;
946 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
948 * Switch to the process tab
950 TabCtrl_SetCurFocus(hTabWnd, 1);
952 * FIXME: Select the process item in the list
954 for (i=0; i<ListView_GetItemCount(hProcessPage); i++) {