[CMAKE]
[reactos.git] / base / applications / taskmgr / applpage.c
1 /*
2 * ReactOS Task Manager
3 *
4 * applpage.c
5 *
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 * 2005 Klemens Friedl <frik85@reactos.at>
8 *
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.
13 *
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.
18 *
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include <precomp.h>
25
26 typedef struct
27 {
28 HWND hWnd;
29 WCHAR szTitle[260];
30 HICON hIcon;
31 BOOL bHung;
32 } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM;
33
34 HWND hApplicationPage; /* Application List Property Page */
35 HWND hApplicationPageListCtrl; /* Application ListCtrl Window */
36 HWND hApplicationPageEndTaskButton; /* Application End Task button */
37 HWND hApplicationPageSwitchToButton; /* Application Switch To button */
38 HWND hApplicationPageNewTaskButton; /* Application New Task button */
39 static int nApplicationPageWidth;
40 static int nApplicationPageHeight;
41 static BOOL bSortAscending = TRUE;
42 DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter);
43 BOOL noApps;
44 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
45 void AddOrUpdateHwnd(HWND hWnd, WCHAR *szTitle, HICON hIcon, BOOL bHung);
46 void ApplicationPageUpdate(void);
47 void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam);
48 void ApplicationPageShowContextMenu1(void);
49 void ApplicationPageShowContextMenu2(void);
50 int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
51 int ProcGetIndexByProcessId(DWORD dwProcessId);
52
53 #ifdef RUN_APPS_PAGE
54 static HANDLE hApplicationThread = NULL;
55 static DWORD dwApplicationThread;
56 #endif
57
58 #if 0
59 void SwitchToThisWindow (
60 HWND hWnd, /* Handle to the window that should be activated */
61 BOOL bRestore /* Restore the window if it is minimized */
62 );
63 #endif
64
65 static INT
66 GetSystemColorDepth(VOID)
67 {
68 DEVMODE pDevMode;
69 INT ColorDepth;
70
71 pDevMode.dmSize = sizeof(DEVMODE);
72 pDevMode.dmDriverExtra = 0;
73
74 if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &pDevMode))
75 return ILC_COLOR;
76
77 switch (pDevMode.dmBitsPerPel)
78 {
79 case 32: ColorDepth = ILC_COLOR32; break;
80 case 24: ColorDepth = ILC_COLOR24; break;
81 case 16: ColorDepth = ILC_COLOR16; break;
82 case 8: ColorDepth = ILC_COLOR8; break;
83 case 4: ColorDepth = ILC_COLOR4; break;
84 default: ColorDepth = ILC_COLOR; break;
85 }
86
87 return ColorDepth;
88 }
89
90 INT_PTR CALLBACK
91 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
92 {
93 RECT rc;
94 int nXDifference;
95 int nYDifference;
96 LV_COLUMN column;
97 WCHAR szTemp[256];
98 int cx, cy;
99
100 switch (message) {
101 case WM_INITDIALOG:
102
103 /* Save the width and height */
104 GetClientRect(hDlg, &rc);
105 nApplicationPageWidth = rc.right;
106 nApplicationPageHeight = rc.bottom;
107
108 /* Update window position */
109 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
110
111 /* Get handles to the controls */
112 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
113 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
114 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
115 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
116
117 SetWindowTextW(hApplicationPageListCtrl, L"Tasks");
118
119 /* Initialize the application page's controls */
120 column.mask = LVCF_TEXT|LVCF_WIDTH;
121
122 LoadStringW(hInst, IDS_TAB_TASK, szTemp, 256);
123 column.pszText = szTemp;
124 column.cx = 250;
125 (void)ListView_InsertColumn(hApplicationPageListCtrl, 0, &column); /* Add the "Task" column */
126 column.mask = LVCF_TEXT|LVCF_WIDTH;
127 LoadStringW(hInst, IDS_TAB_STATUS, szTemp, 256);
128 column.pszText = szTemp;
129 column.cx = 95;
130 (void)ListView_InsertColumn(hApplicationPageListCtrl, 1, &column); /* Add the "Status" column */
131
132 (void)ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(16, 16, GetSystemColorDepth()|ILC_MASK, 0, 1), LVSIL_SMALL);
133 (void)ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(32, 32, GetSystemColorDepth()|ILC_MASK, 0, 1), LVSIL_NORMAL);
134
135 UpdateApplicationListControlViewSetting();
136
137 /* Start our refresh thread */
138 #ifdef RUN_APPS_PAGE
139 hApplicationThread = CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, &dwApplicationThread);
140 #endif
141 return TRUE;
142
143 case WM_DESTROY:
144 /* Close refresh thread */
145 #ifdef RUN_APPS_PAGE
146 EndLocalThread(&hApplicationThread, dwApplicationThread);
147 #endif
148 break;
149
150 case WM_COMMAND:
151
152 /* Handle the button clicks */
153 switch (LOWORD(wParam))
154 {
155 case IDC_ENDTASK:
156 ApplicationPage_OnEndTask();
157 break;
158 case IDC_SWITCHTO:
159 ApplicationPage_OnSwitchTo();
160 break;
161 case IDC_NEWTASK:
162 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
163 break;
164 }
165
166 break;
167
168 case WM_SIZE:
169 if (wParam == SIZE_MINIMIZED)
170 return 0;
171
172 cx = LOWORD(lParam);
173 cy = HIWORD(lParam);
174 nXDifference = cx - nApplicationPageWidth;
175 nYDifference = cy - nApplicationPageHeight;
176 nApplicationPageWidth = cx;
177 nApplicationPageHeight = cy;
178
179 /* Reposition the application page's controls */
180 GetWindowRect(hApplicationPageListCtrl, &rc);
181 cx = (rc.right - rc.left) + nXDifference;
182 cy = (rc.bottom - rc.top) + nYDifference;
183 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
184 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
185
186 GetClientRect(hApplicationPageEndTaskButton, &rc);
187 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(PRECT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
188 cx = rc.left + nXDifference;
189 cy = rc.top + nYDifference;
190 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
191 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
192
193 GetClientRect(hApplicationPageSwitchToButton, &rc);
194 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(PRECT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
195 cx = rc.left + nXDifference;
196 cy = rc.top + nYDifference;
197 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
198 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
199
200 GetClientRect(hApplicationPageNewTaskButton, &rc);
201 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(PRECT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
202 cx = rc.left + nXDifference;
203 cy = rc.top + nYDifference;
204 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
205 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
206
207 break;
208
209 case WM_NOTIFY:
210 ApplicationPageOnNotify(wParam, lParam);
211 break;
212
213 case WM_KEYDOWN:
214 if (wParam == VK_DELETE)
215 ProcessPage_OnEndProcess();
216 break;
217
218 }
219
220 return 0;
221 }
222
223 void RefreshApplicationPage(void)
224 {
225 #ifdef RUN_APPS_PAGE
226 /* Signal the event so that our refresh thread */
227 /* will wake up and refresh the application page */
228 PostThreadMessage(dwApplicationThread, WM_TIMER, 0, 0);
229 #endif
230 }
231
232 void UpdateApplicationListControlViewSetting(void)
233 {
234 DWORD dwStyle = GetWindowLongPtrW(hApplicationPageListCtrl, GWL_STYLE);
235
236 dwStyle &= ~(LVS_REPORT | LVS_ICON | LVS_LIST | LVS_SMALLICON);
237
238 switch (TaskManagerSettings.ViewMode) {
239 case ID_VIEW_LARGE: dwStyle |= LVS_ICON; break;
240 case ID_VIEW_SMALL: dwStyle |= LVS_SMALLICON; break;
241 case ID_VIEW_DETAILS: dwStyle |= LVS_REPORT; break;
242 }
243 SetWindowLongPtrW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
244
245 RefreshApplicationPage();
246 }
247
248 DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
249 {
250 MSG msg;
251 INT i;
252 BOOL bItemRemoved = FALSE;
253 LV_ITEM item;
254 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
255 HIMAGELIST hImageListLarge;
256 HIMAGELIST hImageListSmall;
257
258 /* If we couldn't create the event then exit the thread */
259 while (1)
260 {
261 /* Wait for an the event or application close */
262 if (GetMessage(&msg, NULL, 0, 0) <= 0)
263 return 0;
264
265 if (msg.message == WM_TIMER)
266 {
267 /*
268 * FIXME:
269 *
270 * Should this be EnumDesktopWindows() instead?
271 */
272 noApps = TRUE;
273 EnumWindows(EnumWindowsProc, 0);
274 if (noApps)
275 (void)ListView_DeleteAllItems(hApplicationPageListCtrl);
276
277 /* Get the image lists */
278 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL);
279 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL);
280
281 /* Check to see if we need to remove any items from the list */
282 for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--)
283 {
284 memset(&item, 0, sizeof(LV_ITEM));
285 item.mask = LVIF_IMAGE|LVIF_PARAM;
286 item.iItem = i;
287 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
288
289 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
290 if (!IsWindow(pAPLI->hWnd)||
291 (wcslen(pAPLI->szTitle) <= 0) ||
292 !IsWindowVisible(pAPLI->hWnd) ||
293 (GetParent(pAPLI->hWnd) != NULL) ||
294 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
295 (GetWindowLongPtr(pAPLI->hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
296 {
297 ImageList_Remove(hImageListLarge, item.iItem);
298 ImageList_Remove(hImageListSmall, item.iItem);
299
300 (void)ListView_DeleteItem(hApplicationPageListCtrl, item.iItem);
301 HeapFree(GetProcessHeap(), 0, pAPLI);
302 bItemRemoved = TRUE;
303 }
304 }
305
306 /*
307 * If an item was removed from the list then
308 * we need to resync all the items with the
309 * image list
310 */
311 if (bItemRemoved)
312 {
313 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
314 {
315 memset(&item, 0, sizeof(LV_ITEM));
316 item.mask = LVIF_IMAGE;
317 item.iItem = i;
318 item.iImage = i;
319 (void)ListView_SetItem(hApplicationPageListCtrl, &item);
320 }
321 bItemRemoved = FALSE;
322 }
323
324 ApplicationPageUpdate();
325 }
326 }
327 }
328
329 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
330 {
331 HICON hIcon;
332 WCHAR szText[260];
333 BOOL bLargeIcon;
334 BOOL bHung = FALSE;
335 HICON* xhIcon = (HICON*)&hIcon;
336
337 typedef int (FAR __stdcall *IsHungAppWindowProc)(HWND);
338 IsHungAppWindowProc IsHungAppWindow;
339
340
341 /* Skip our window */
342 if (hWnd == hMainWnd)
343 return TRUE;
344
345 bLargeIcon = (TaskManagerSettings.ViewMode == ID_VIEW_LARGE);
346
347 GetWindowTextW(hWnd, szText, 260); /* Get the window text */
348
349 /* Check and see if this is a top-level app window */
350 if ((wcslen(szText) <= 0) ||
351 !IsWindowVisible(hWnd) ||
352 (GetParent(hWnd) != NULL) ||
353 (GetWindow(hWnd, GW_OWNER) != NULL) ||
354 (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
355 {
356 return TRUE; /* Skip this window */
357 }
358
359 noApps = FALSE;
360 /* Get the icon for this window */
361 hIcon = NULL;
362 SendMessageTimeoutW(hWnd, WM_GETICON,bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)xhIcon);
363
364 if (!hIcon)
365 {
366 hIcon = (HICON)(LONG_PTR)GetClassLongPtrW(hWnd, bLargeIcon ? GCL_HICON : GCL_HICONSM);
367 if (!hIcon) hIcon = (HICON)(LONG_PTR)GetClassLongPtrW(hWnd, bLargeIcon ? GCL_HICONSM : GCL_HICON);
368 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)xhIcon);
369 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)xhIcon);
370 }
371
372 if (!hIcon)
373 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
374
375 bHung = FALSE;
376
377 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(L"USER32.DLL"), "IsHungAppWindow");
378
379 if (IsHungAppWindow)
380 bHung = IsHungAppWindow(hWnd);
381
382 AddOrUpdateHwnd(hWnd, szText, hIcon, bHung);
383
384 return TRUE;
385 }
386
387 void AddOrUpdateHwnd(HWND hWnd, WCHAR *szTitle, HICON hIcon, BOOL bHung)
388 {
389 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
390 HIMAGELIST hImageListLarge;
391 HIMAGELIST hImageListSmall;
392 LV_ITEM item;
393 int i;
394 BOOL bAlreadyInList = FALSE;
395
396 memset(&item, 0, sizeof(LV_ITEM));
397
398 /* Get the image lists */
399 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL);
400 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL);
401
402 /* Check to see if it's already in our list */
403 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
404 {
405 memset(&item, 0, sizeof(LV_ITEM));
406 item.mask = LVIF_IMAGE|LVIF_PARAM;
407 item.iItem = i;
408 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
409
410 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
411 if (pAPLI->hWnd == hWnd)
412 {
413 bAlreadyInList = TRUE;
414 break;
415 }
416 }
417
418 /* If it is already in the list then update it if necessary */
419 if (bAlreadyInList)
420 {
421 /* Check to see if anything needs updating */
422 if ((pAPLI->hIcon != hIcon) ||
423 (_wcsicmp(pAPLI->szTitle, szTitle) != 0) ||
424 (pAPLI->bHung != bHung))
425 {
426 /* Update the structure */
427 pAPLI->hIcon = hIcon;
428 pAPLI->bHung = bHung;
429 wcscpy(pAPLI->szTitle, szTitle);
430
431 /* Update the image list */
432 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
433 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
434
435 /* Update the list view */
436 (void)ListView_RedrawItems(hApplicationPageListCtrl, 0, ListView_GetItemCount(hApplicationPageListCtrl));
437 /* UpdateWindow(hApplicationPageListCtrl); */
438 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
439 }
440 }
441 /* It is not already in the list so add it */
442 else
443 {
444 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
445
446 pAPLI->hWnd = hWnd;
447 pAPLI->hIcon = hIcon;
448 pAPLI->bHung = bHung;
449 wcscpy(pAPLI->szTitle, szTitle);
450
451 /* Add the item to the list */
452 memset(&item, 0, sizeof(LV_ITEM));
453 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
454 ImageList_AddIcon(hImageListLarge, hIcon);
455 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
456 item.pszText = LPSTR_TEXTCALLBACK;
457 item.iItem = ListView_GetItemCount(hApplicationPageListCtrl);
458 item.lParam = (LPARAM)pAPLI;
459 (void)ListView_InsertItem(hApplicationPageListCtrl, &item);
460 }
461 return;
462 }
463
464 void ApplicationPageUpdate(void)
465 {
466 /* Enable or disable the "End Task" & "Switch To" buttons */
467 if (ListView_GetSelectedCount(hApplicationPageListCtrl))
468 {
469 EnableWindow(hApplicationPageEndTaskButton, TRUE);
470 }
471 else
472 {
473 EnableWindow(hApplicationPageEndTaskButton, FALSE);
474 }
475 /* Enable "Switch To" button only if one app is selected */
476 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1 )
477 {
478 EnableWindow(hApplicationPageSwitchToButton, TRUE);
479 }
480 else
481 {
482 EnableWindow(hApplicationPageSwitchToButton, FALSE);
483 }
484
485 /* If we are on the applications tab the windows menu will be */
486 /* present on the menu bar so enable & disable the menu items */
487 if (TabCtrl_GetCurSel(hTabWnd) == 0)
488 {
489 HMENU hMenu;
490 HMENU hWindowsMenu;
491
492 hMenu = GetMenu(hMainWnd);
493 hWindowsMenu = GetSubMenu(hMenu, 3);
494
495 /* Only one item selected */
496 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1)
497 {
498 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
499 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
500 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
501 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
502 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
503 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
504 }
505 /* More than one item selected */
506 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1)
507 {
508 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
509 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
510 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
511 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
512 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
513 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
514 }
515 /* No items selected */
516 else
517 {
518 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
519 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
520 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
521 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
522 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
523 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
524 }
525 }
526 }
527
528 void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
529 {
530 int idctrl;
531 LPNMHDR pnmh;
532 LPNM_LISTVIEW pnmv;
533 LV_DISPINFO* pnmdi;
534 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
535 WCHAR szMsg[256];
536
537
538 idctrl = (int) wParam;
539 pnmh = (LPNMHDR) lParam;
540 pnmv = (LPNM_LISTVIEW) lParam;
541 pnmdi = (LV_DISPINFO*) lParam;
542
543 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
544 switch (pnmh->code) {
545 case LVN_ITEMCHANGED:
546 ApplicationPageUpdate();
547 break;
548
549 case LVN_GETDISPINFO:
550 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
551
552 /* Update the item text */
553 if (pnmdi->item.iSubItem == 0)
554 {
555 wcsncpy(pnmdi->item.pszText, pAPLI->szTitle, pnmdi->item.cchTextMax);
556 }
557
558 /* Update the item status */
559 else if (pnmdi->item.iSubItem == 1)
560 {
561 if (pAPLI->bHung)
562 {
563 LoadStringW( GetModuleHandleW(NULL), IDS_Not_Responding , szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
564 }
565 else
566 {
567 LoadStringW( GetModuleHandleW(NULL), IDS_Running, (LPWSTR) szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
568 }
569 wcsncpy(pnmdi->item.pszText, szMsg, pnmdi->item.cchTextMax);
570 }
571
572 break;
573
574 case NM_RCLICK:
575
576 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
577 {
578 ApplicationPageShowContextMenu1();
579 }
580 else
581 {
582 ApplicationPageShowContextMenu2();
583 }
584
585 break;
586
587 case NM_DBLCLK:
588
589 ApplicationPage_OnSwitchTo();
590
591 break;
592
593 case LVN_KEYDOWN:
594
595 if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE)
596 ApplicationPage_OnEndTask();
597
598 break;
599
600 }
601 }
602 else if (pnmh->hwndFrom == ListView_GetHeader(hApplicationPageListCtrl))
603 {
604 switch (pnmh->code)
605 {
606 case NM_RCLICK:
607
608 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
609 {
610 ApplicationPageShowContextMenu1();
611 }
612 else
613 {
614 ApplicationPageShowContextMenu2();
615 }
616
617 break;
618
619 case HDN_ITEMCLICK:
620
621 (void)ListView_SortItems(hApplicationPageListCtrl, ApplicationPageCompareFunc, 0);
622 bSortAscending = !bSortAscending;
623
624 break;
625 }
626 }
627
628 }
629
630 void ApplicationPageShowContextMenu1(void)
631 {
632 HMENU hMenu;
633 HMENU hSubMenu;
634 POINT pt;
635
636 GetCursorPos(&pt);
637
638 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
639 hSubMenu = GetSubMenu(hMenu, 0);
640
641 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND);
642
643 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
644
645 DestroyMenu(hMenu);
646 }
647
648 void ApplicationPageShowContextMenu2(void)
649 {
650 HMENU hMenu;
651 HMENU hSubMenu;
652 POINT pt;
653
654 GetCursorPos(&pt);
655
656 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
657 hSubMenu = GetSubMenu(hMenu, 0);
658
659 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1)
660 {
661 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
662 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
663 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
664 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
665 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
666 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
667 }
668 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1)
669 {
670 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
671 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
672 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
673 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
674 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
675 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
676 }
677 else
678 {
679 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
680 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
681 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
682 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
683 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
684 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
685 }
686
687 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
688
689 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
690
691 DestroyMenu(hMenu);
692 }
693
694 void ApplicationPage_OnView(DWORD dwMode)
695 {
696 HMENU hMenu;
697 HMENU hViewMenu;
698
699 hMenu = GetMenu(hMainWnd);
700 hViewMenu = GetSubMenu(hMenu, 2);
701
702 TaskManagerSettings.ViewMode = dwMode;
703 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, dwMode, MF_BYCOMMAND);
704
705 UpdateApplicationListControlViewSetting();
706 }
707
708 void ApplicationPage_OnWindowsTile(DWORD dwMode)
709 {
710 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
711 LV_ITEM item;
712 int i;
713 HWND* hWndArray;
714 int nWndCount;
715
716 hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
717 nWndCount = 0;
718
719 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
720 memset(&item, 0, sizeof(LV_ITEM));
721 item.mask = LVIF_STATE|LVIF_PARAM;
722 item.iItem = i;
723 item.stateMask = (UINT)-1;
724 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
725
726 if (item.state & LVIS_SELECTED) {
727 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
728 if (pAPLI) {
729 hWndArray[nWndCount] = pAPLI->hWnd;
730 nWndCount++;
731 }
732 }
733 }
734
735 TileWindows(NULL, dwMode, NULL, nWndCount, hWndArray);
736 HeapFree(GetProcessHeap(), 0, hWndArray);
737 }
738
739 void ApplicationPage_OnWindowsMinimize(void)
740 {
741 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
742 LV_ITEM item;
743 int i;
744
745 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
746 memset(&item, 0, sizeof(LV_ITEM));
747 item.mask = LVIF_STATE|LVIF_PARAM;
748 item.iItem = i;
749 item.stateMask = (UINT)-1;
750 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
751 if (item.state & LVIS_SELECTED) {
752 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
753 if (pAPLI) {
754 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
755 }
756 }
757 }
758 }
759
760 void ApplicationPage_OnWindowsMaximize(void)
761 {
762 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
763 LV_ITEM item;
764 int i;
765
766 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
767 memset(&item, 0, sizeof(LV_ITEM));
768 item.mask = LVIF_STATE|LVIF_PARAM;
769 item.iItem = i;
770 item.stateMask = (UINT)-1;
771 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
772 if (item.state & LVIS_SELECTED) {
773 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
774 if (pAPLI) {
775 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
776 }
777 }
778 }
779 }
780
781 void ApplicationPage_OnWindowsCascade(void)
782 {
783 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
784 LV_ITEM item;
785 int i;
786 HWND* hWndArray;
787 int nWndCount;
788
789 hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
790 nWndCount = 0;
791
792 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
793 memset(&item, 0, sizeof(LV_ITEM));
794 item.mask = LVIF_STATE|LVIF_PARAM;
795 item.iItem = i;
796 item.stateMask = (UINT)-1;
797 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
798 if (item.state & LVIS_SELECTED) {
799 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
800 if (pAPLI) {
801 hWndArray[nWndCount] = pAPLI->hWnd;
802 nWndCount++;
803 }
804 }
805 }
806 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
807 HeapFree(GetProcessHeap(), 0, hWndArray);
808 }
809
810 void ApplicationPage_OnWindowsBringToFront(void)
811 {
812 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
813 LV_ITEM item;
814 int i;
815
816 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
817 memset(&item, 0, sizeof(LV_ITEM));
818 item.mask = LVIF_STATE|LVIF_PARAM;
819 item.iItem = i;
820 item.stateMask = (UINT)-1;
821 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
822 if (item.state & LVIS_SELECTED) {
823 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
824 break;
825 }
826 }
827 if (pAPLI) {
828 if (IsIconic(pAPLI->hWnd))
829 ShowWindow(pAPLI->hWnd, SW_RESTORE);
830 BringWindowToTop(pAPLI->hWnd);
831 }
832 }
833
834 void ApplicationPage_OnSwitchTo(void)
835 {
836 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
837 LV_ITEM item;
838 int i;
839
840 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
841 memset(&item, 0, sizeof(LV_ITEM));
842 item.mask = LVIF_STATE|LVIF_PARAM;
843 item.iItem = i;
844 item.stateMask = (UINT)-1;
845 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
846
847 if (item.state & LVIS_SELECTED) {
848 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
849 break;
850 }
851 }
852 if (pAPLI) {
853 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
854 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
855
856 HMODULE hUser32 = GetModuleHandleW(L"USER32");
857 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
858 if (SwitchToThisWindow) {
859 SwitchToThisWindow(pAPLI->hWnd, TRUE);
860 } else {
861 if (IsIconic(pAPLI->hWnd))
862 ShowWindow(pAPLI->hWnd, SW_RESTORE);
863 BringWindowToTop(pAPLI->hWnd);
864 SetForegroundWindow(pAPLI->hWnd);
865 }
866 if (TaskManagerSettings.MinimizeOnUse)
867 ShowWindow(hMainWnd, SW_MINIMIZE);
868 }
869 }
870
871 void ApplicationPage_OnEndTask(void)
872 {
873 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
874 LV_ITEM item;
875 int i;
876
877 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
878 memset(&item, 0, sizeof(LV_ITEM));
879 item.mask = LVIF_STATE|LVIF_PARAM;
880 item.iItem = i;
881 item.stateMask = (UINT)-1;
882 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
883 if (item.state & LVIS_SELECTED) {
884 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
885 if (pAPLI) {
886 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
887 }
888 }
889 }
890 }
891
892 void ApplicationPage_OnGotoProcess(void)
893 {
894 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
895 LV_ITEM item;
896 int i;
897
898 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
899 memset(&item, 0, sizeof(LV_ITEM));
900 item.mask = LVIF_STATE|LVIF_PARAM;
901 item.iItem = i;
902 item.stateMask = (UINT)-1;
903 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
904 if (item.state & LVIS_SELECTED) {
905 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
906 break;
907 }
908 }
909 if (pAPLI) {
910 DWORD dwProcessId;
911
912 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
913 /*
914 * Switch to the process tab
915 */
916 TabCtrl_SetCurFocus(hTabWnd, 1);
917 /*
918 * Select the process item in the list
919 */
920 i = ProcGetIndexByProcessId(dwProcessId);
921 if (i != -1)
922 {
923 ListView_SetItemState(hProcessPageListCtrl,
924 i,
925 LVIS_SELECTED | LVIS_FOCUSED,
926 LVIS_SELECTED | LVIS_FOCUSED);
927 (void)ListView_EnsureVisible(hProcessPageListCtrl,
928 i,
929 FALSE);
930 }
931 }
932 }
933
934 int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
935 {
936 LPAPPLICATION_PAGE_LIST_ITEM Param1;
937 LPAPPLICATION_PAGE_LIST_ITEM Param2;
938
939 if (bSortAscending) {
940 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
941 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
942 } else {
943 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
944 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
945 }
946 return wcscmp(Param1->szTitle, Param2->szTitle);
947 }