Sync with trunk (r48545)
[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 }
214
215 return 0;
216 }
217
218 void RefreshApplicationPage(void)
219 {
220 #ifdef RUN_APPS_PAGE
221 /* Signal the event so that our refresh thread */
222 /* will wake up and refresh the application page */
223 PostThreadMessage(dwApplicationThread, WM_TIMER, 0, 0);
224 #endif
225 }
226
227 void UpdateApplicationListControlViewSetting(void)
228 {
229 DWORD dwStyle = GetWindowLongPtrW(hApplicationPageListCtrl, GWL_STYLE);
230
231 dwStyle &= ~(LVS_REPORT | LVS_ICON | LVS_LIST | LVS_SMALLICON);
232
233 switch (TaskManagerSettings.ViewMode) {
234 case ID_VIEW_LARGE: dwStyle |= LVS_ICON; break;
235 case ID_VIEW_SMALL: dwStyle |= LVS_SMALLICON; break;
236 case ID_VIEW_DETAILS: dwStyle |= LVS_REPORT; break;
237 }
238 SetWindowLongPtrW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
239
240 RefreshApplicationPage();
241 }
242
243 DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
244 {
245 MSG msg;
246 INT i;
247 BOOL bItemRemoved = FALSE;
248 LV_ITEM item;
249 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
250 HIMAGELIST hImageListLarge;
251 HIMAGELIST hImageListSmall;
252
253 /* If we couldn't create the event then exit the thread */
254 while (1)
255 {
256 /* Wait for an the event or application close */
257 if (GetMessage(&msg, NULL, 0, 0) <= 0)
258 return 0;
259
260 if (msg.message == WM_TIMER)
261 {
262 /*
263 * FIXME:
264 *
265 * Should this be EnumDesktopWindows() instead?
266 */
267 noApps = TRUE;
268 EnumWindows(EnumWindowsProc, 0);
269 if (noApps)
270 (void)ListView_DeleteAllItems(hApplicationPageListCtrl);
271
272 /* Get the image lists */
273 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL);
274 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL);
275
276 /* Check to see if we need to remove any items from the list */
277 for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--)
278 {
279 memset(&item, 0, sizeof(LV_ITEM));
280 item.mask = LVIF_IMAGE|LVIF_PARAM;
281 item.iItem = i;
282 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
283
284 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
285 if (!IsWindow(pAPLI->hWnd)||
286 (wcslen(pAPLI->szTitle) <= 0) ||
287 !IsWindowVisible(pAPLI->hWnd) ||
288 (GetParent(pAPLI->hWnd) != NULL) ||
289 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
290 (GetWindowLongPtr(pAPLI->hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
291 {
292 ImageList_Remove(hImageListLarge, item.iItem);
293 ImageList_Remove(hImageListSmall, item.iItem);
294
295 (void)ListView_DeleteItem(hApplicationPageListCtrl, item.iItem);
296 HeapFree(GetProcessHeap(), 0, pAPLI);
297 bItemRemoved = TRUE;
298 }
299 }
300
301 /*
302 * If an item was removed from the list then
303 * we need to resync all the items with the
304 * image list
305 */
306 if (bItemRemoved)
307 {
308 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
309 {
310 memset(&item, 0, sizeof(LV_ITEM));
311 item.mask = LVIF_IMAGE;
312 item.iItem = i;
313 item.iImage = i;
314 (void)ListView_SetItem(hApplicationPageListCtrl, &item);
315 }
316 bItemRemoved = FALSE;
317 }
318
319 ApplicationPageUpdate();
320 }
321 }
322 }
323
324 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
325 {
326 HICON hIcon;
327 WCHAR szText[260];
328 BOOL bLargeIcon;
329 BOOL bHung = FALSE;
330 HICON* xhIcon = (HICON*)&hIcon;
331
332 typedef int (FAR __stdcall *IsHungAppWindowProc)(HWND);
333 IsHungAppWindowProc IsHungAppWindow;
334
335
336 /* Skip our window */
337 if (hWnd == hMainWnd)
338 return TRUE;
339
340 bLargeIcon = (TaskManagerSettings.ViewMode == ID_VIEW_LARGE);
341
342 GetWindowTextW(hWnd, szText, 260); /* Get the window text */
343
344 /* Check and see if this is a top-level app window */
345 if ((wcslen(szText) <= 0) ||
346 !IsWindowVisible(hWnd) ||
347 (GetParent(hWnd) != NULL) ||
348 (GetWindow(hWnd, GW_OWNER) != NULL) ||
349 (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
350 {
351 return TRUE; /* Skip this window */
352 }
353
354 noApps = FALSE;
355 /* Get the icon for this window */
356 hIcon = NULL;
357 SendMessageTimeoutW(hWnd, WM_GETICON,bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)xhIcon);
358
359 if (!hIcon)
360 {
361 hIcon = (HICON)(LONG_PTR)GetClassLongPtrW(hWnd, bLargeIcon ? GCL_HICON : GCL_HICONSM);
362 if (!hIcon) hIcon = (HICON)(LONG_PTR)GetClassLongPtrW(hWnd, bLargeIcon ? GCL_HICONSM : GCL_HICON);
363 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)xhIcon);
364 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)xhIcon);
365 }
366
367 if (!hIcon)
368 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
369
370 bHung = FALSE;
371
372 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(L"USER32.DLL"), "IsHungAppWindow");
373
374 if (IsHungAppWindow)
375 bHung = IsHungAppWindow(hWnd);
376
377 AddOrUpdateHwnd(hWnd, szText, hIcon, bHung);
378
379 return TRUE;
380 }
381
382 void AddOrUpdateHwnd(HWND hWnd, WCHAR *szTitle, HICON hIcon, BOOL bHung)
383 {
384 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
385 HIMAGELIST hImageListLarge;
386 HIMAGELIST hImageListSmall;
387 LV_ITEM item;
388 int i;
389 BOOL bAlreadyInList = FALSE;
390
391 memset(&item, 0, sizeof(LV_ITEM));
392
393 /* Get the image lists */
394 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL);
395 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL);
396
397 /* Check to see if it's already in our list */
398 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
399 {
400 memset(&item, 0, sizeof(LV_ITEM));
401 item.mask = LVIF_IMAGE|LVIF_PARAM;
402 item.iItem = i;
403 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
404
405 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
406 if (pAPLI->hWnd == hWnd)
407 {
408 bAlreadyInList = TRUE;
409 break;
410 }
411 }
412
413 /* If it is already in the list then update it if necessary */
414 if (bAlreadyInList)
415 {
416 /* Check to see if anything needs updating */
417 if ((pAPLI->hIcon != hIcon) ||
418 (_wcsicmp(pAPLI->szTitle, szTitle) != 0) ||
419 (pAPLI->bHung != bHung))
420 {
421 /* Update the structure */
422 pAPLI->hIcon = hIcon;
423 pAPLI->bHung = bHung;
424 wcscpy(pAPLI->szTitle, szTitle);
425
426 /* Update the image list */
427 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
428 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
429
430 /* Update the list view */
431 (void)ListView_RedrawItems(hApplicationPageListCtrl, 0, ListView_GetItemCount(hApplicationPageListCtrl));
432 /* UpdateWindow(hApplicationPageListCtrl); */
433 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
434 }
435 }
436 /* It is not already in the list so add it */
437 else
438 {
439 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
440
441 pAPLI->hWnd = hWnd;
442 pAPLI->hIcon = hIcon;
443 pAPLI->bHung = bHung;
444 wcscpy(pAPLI->szTitle, szTitle);
445
446 /* Add the item to the list */
447 memset(&item, 0, sizeof(LV_ITEM));
448 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
449 ImageList_AddIcon(hImageListLarge, hIcon);
450 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
451 item.pszText = LPSTR_TEXTCALLBACK;
452 item.iItem = ListView_GetItemCount(hApplicationPageListCtrl);
453 item.lParam = (LPARAM)pAPLI;
454 (void)ListView_InsertItem(hApplicationPageListCtrl, &item);
455 }
456 return;
457 }
458
459 void ApplicationPageUpdate(void)
460 {
461 /* Enable or disable the "End Task" & "Switch To" buttons */
462 if (ListView_GetSelectedCount(hApplicationPageListCtrl))
463 {
464 EnableWindow(hApplicationPageEndTaskButton, TRUE);
465 }
466 else
467 {
468 EnableWindow(hApplicationPageEndTaskButton, FALSE);
469 }
470 /* Enable "Switch To" button only if one app is selected */
471 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1 )
472 {
473 EnableWindow(hApplicationPageSwitchToButton, TRUE);
474 }
475 else
476 {
477 EnableWindow(hApplicationPageSwitchToButton, FALSE);
478 }
479
480 /* If we are on the applications tab the windows menu will be */
481 /* present on the menu bar so enable & disable the menu items */
482 if (TabCtrl_GetCurSel(hTabWnd) == 0)
483 {
484 HMENU hMenu;
485 HMENU hWindowsMenu;
486
487 hMenu = GetMenu(hMainWnd);
488 hWindowsMenu = GetSubMenu(hMenu, 3);
489
490 /* Only one item selected */
491 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1)
492 {
493 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
494 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
495 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
496 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
497 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
498 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
499 }
500 /* More than one item selected */
501 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1)
502 {
503 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
504 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
505 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
506 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
507 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
508 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
509 }
510 /* No items selected */
511 else
512 {
513 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
514 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
515 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
516 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
517 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
518 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
519 }
520 }
521 }
522
523 void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
524 {
525 int idctrl;
526 LPNMHDR pnmh;
527 LPNM_LISTVIEW pnmv;
528 LV_DISPINFO* pnmdi;
529 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
530 WCHAR szMsg[256];
531
532
533 idctrl = (int) wParam;
534 pnmh = (LPNMHDR) lParam;
535 pnmv = (LPNM_LISTVIEW) lParam;
536 pnmdi = (LV_DISPINFO*) lParam;
537
538 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
539 switch (pnmh->code) {
540 case LVN_ITEMCHANGED:
541 ApplicationPageUpdate();
542 break;
543
544 case LVN_GETDISPINFO:
545 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
546
547 /* Update the item text */
548 if (pnmdi->item.iSubItem == 0)
549 {
550 wcsncpy(pnmdi->item.pszText, pAPLI->szTitle, pnmdi->item.cchTextMax);
551 }
552
553 /* Update the item status */
554 else if (pnmdi->item.iSubItem == 1)
555 {
556 if (pAPLI->bHung)
557 {
558 LoadStringW( GetModuleHandleW(NULL), IDS_Not_Responding , szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
559 }
560 else
561 {
562 LoadStringW( GetModuleHandleW(NULL), IDS_Running, (LPWSTR) szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
563 }
564 wcsncpy(pnmdi->item.pszText, szMsg, pnmdi->item.cchTextMax);
565 }
566
567 break;
568
569 case NM_RCLICK:
570
571 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
572 {
573 ApplicationPageShowContextMenu1();
574 }
575 else
576 {
577 ApplicationPageShowContextMenu2();
578 }
579
580 break;
581
582 case NM_DBLCLK:
583
584 ApplicationPage_OnSwitchTo();
585
586 break;
587 }
588 }
589 else if (pnmh->hwndFrom == ListView_GetHeader(hApplicationPageListCtrl))
590 {
591 switch (pnmh->code)
592 {
593 case NM_RCLICK:
594
595 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
596 {
597 ApplicationPageShowContextMenu1();
598 }
599 else
600 {
601 ApplicationPageShowContextMenu2();
602 }
603
604 break;
605
606 case HDN_ITEMCLICK:
607
608 (void)ListView_SortItems(hApplicationPageListCtrl, ApplicationPageCompareFunc, 0);
609 bSortAscending = !bSortAscending;
610
611 break;
612 }
613 }
614
615 }
616
617 void ApplicationPageShowContextMenu1(void)
618 {
619 HMENU hMenu;
620 HMENU hSubMenu;
621 POINT pt;
622
623 GetCursorPos(&pt);
624
625 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
626 hSubMenu = GetSubMenu(hMenu, 0);
627
628 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND);
629
630 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
631
632 DestroyMenu(hMenu);
633 }
634
635 void ApplicationPageShowContextMenu2(void)
636 {
637 HMENU hMenu;
638 HMENU hSubMenu;
639 POINT pt;
640
641 GetCursorPos(&pt);
642
643 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
644 hSubMenu = GetSubMenu(hMenu, 0);
645
646 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1)
647 {
648 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
649 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
650 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
651 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
652 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
653 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
654 }
655 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1)
656 {
657 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
658 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
659 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
660 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
661 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
662 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
663 }
664 else
665 {
666 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
667 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
668 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
669 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
670 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
671 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
672 }
673
674 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
675
676 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
677
678 DestroyMenu(hMenu);
679 }
680
681 void ApplicationPage_OnView(DWORD dwMode)
682 {
683 HMENU hMenu;
684 HMENU hViewMenu;
685
686 hMenu = GetMenu(hMainWnd);
687 hViewMenu = GetSubMenu(hMenu, 2);
688
689 TaskManagerSettings.ViewMode = dwMode;
690 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, dwMode, MF_BYCOMMAND);
691
692 UpdateApplicationListControlViewSetting();
693 }
694
695 void ApplicationPage_OnWindowsTile(DWORD dwMode)
696 {
697 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
698 LV_ITEM item;
699 int i;
700 HWND* hWndArray;
701 int nWndCount;
702
703 hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
704 nWndCount = 0;
705
706 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
707 memset(&item, 0, sizeof(LV_ITEM));
708 item.mask = LVIF_STATE|LVIF_PARAM;
709 item.iItem = i;
710 item.stateMask = (UINT)-1;
711 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
712
713 if (item.state & LVIS_SELECTED) {
714 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
715 if (pAPLI) {
716 hWndArray[nWndCount] = pAPLI->hWnd;
717 nWndCount++;
718 }
719 }
720 }
721
722 TileWindows(NULL, dwMode, NULL, nWndCount, hWndArray);
723 HeapFree(GetProcessHeap(), 0, hWndArray);
724 }
725
726 void ApplicationPage_OnWindowsMinimize(void)
727 {
728 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
729 LV_ITEM item;
730 int i;
731
732 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
733 memset(&item, 0, sizeof(LV_ITEM));
734 item.mask = LVIF_STATE|LVIF_PARAM;
735 item.iItem = i;
736 item.stateMask = (UINT)-1;
737 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
738 if (item.state & LVIS_SELECTED) {
739 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
740 if (pAPLI) {
741 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
742 }
743 }
744 }
745 }
746
747 void ApplicationPage_OnWindowsMaximize(void)
748 {
749 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
750 LV_ITEM item;
751 int i;
752
753 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
754 memset(&item, 0, sizeof(LV_ITEM));
755 item.mask = LVIF_STATE|LVIF_PARAM;
756 item.iItem = i;
757 item.stateMask = (UINT)-1;
758 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
759 if (item.state & LVIS_SELECTED) {
760 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
761 if (pAPLI) {
762 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
763 }
764 }
765 }
766 }
767
768 void ApplicationPage_OnWindowsCascade(void)
769 {
770 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
771 LV_ITEM item;
772 int i;
773 HWND* hWndArray;
774 int nWndCount;
775
776 hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
777 nWndCount = 0;
778
779 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
780 memset(&item, 0, sizeof(LV_ITEM));
781 item.mask = LVIF_STATE|LVIF_PARAM;
782 item.iItem = i;
783 item.stateMask = (UINT)-1;
784 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
785 if (item.state & LVIS_SELECTED) {
786 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
787 if (pAPLI) {
788 hWndArray[nWndCount] = pAPLI->hWnd;
789 nWndCount++;
790 }
791 }
792 }
793 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
794 HeapFree(GetProcessHeap(), 0, hWndArray);
795 }
796
797 void ApplicationPage_OnWindowsBringToFront(void)
798 {
799 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
800 LV_ITEM item;
801 int i;
802
803 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
804 memset(&item, 0, sizeof(LV_ITEM));
805 item.mask = LVIF_STATE|LVIF_PARAM;
806 item.iItem = i;
807 item.stateMask = (UINT)-1;
808 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
809 if (item.state & LVIS_SELECTED) {
810 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
811 break;
812 }
813 }
814 if (pAPLI) {
815 if (IsIconic(pAPLI->hWnd))
816 ShowWindow(pAPLI->hWnd, SW_RESTORE);
817 BringWindowToTop(pAPLI->hWnd);
818 }
819 }
820
821 void ApplicationPage_OnSwitchTo(void)
822 {
823 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
824 LV_ITEM item;
825 int i;
826
827 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
828 memset(&item, 0, sizeof(LV_ITEM));
829 item.mask = LVIF_STATE|LVIF_PARAM;
830 item.iItem = i;
831 item.stateMask = (UINT)-1;
832 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
833
834 if (item.state & LVIS_SELECTED) {
835 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
836 break;
837 }
838 }
839 if (pAPLI) {
840 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
841 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
842
843 HMODULE hUser32 = GetModuleHandleW(L"USER32");
844 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
845 if (SwitchToThisWindow) {
846 SwitchToThisWindow(pAPLI->hWnd, TRUE);
847 } else {
848 if (IsIconic(pAPLI->hWnd))
849 ShowWindow(pAPLI->hWnd, SW_RESTORE);
850 BringWindowToTop(pAPLI->hWnd);
851 SetForegroundWindow(pAPLI->hWnd);
852 }
853 if (TaskManagerSettings.MinimizeOnUse)
854 ShowWindow(hMainWnd, SW_MINIMIZE);
855 }
856 }
857
858 void ApplicationPage_OnEndTask(void)
859 {
860 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
861 LV_ITEM item;
862 int i;
863
864 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
865 memset(&item, 0, sizeof(LV_ITEM));
866 item.mask = LVIF_STATE|LVIF_PARAM;
867 item.iItem = i;
868 item.stateMask = (UINT)-1;
869 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
870 if (item.state & LVIS_SELECTED) {
871 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
872 if (pAPLI) {
873 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
874 }
875 }
876 }
877 }
878
879 void ApplicationPage_OnGotoProcess(void)
880 {
881 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
882 LV_ITEM item;
883 int i;
884
885 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
886 memset(&item, 0, sizeof(LV_ITEM));
887 item.mask = LVIF_STATE|LVIF_PARAM;
888 item.iItem = i;
889 item.stateMask = (UINT)-1;
890 (void)ListView_GetItem(hApplicationPageListCtrl, &item);
891 if (item.state & LVIS_SELECTED) {
892 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
893 break;
894 }
895 }
896 if (pAPLI) {
897 DWORD dwProcessId;
898
899 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
900 /*
901 * Switch to the process tab
902 */
903 TabCtrl_SetCurFocus(hTabWnd, 1);
904 /*
905 * Select the process item in the list
906 */
907 i = ProcGetIndexByProcessId(dwProcessId);
908 if (i != -1)
909 {
910 ListView_SetItemState(hProcessPageListCtrl,
911 i,
912 LVIS_SELECTED | LVIS_FOCUSED,
913 LVIS_SELECTED | LVIS_FOCUSED);
914 (void)ListView_EnsureVisible(hProcessPageListCtrl,
915 i,
916 FALSE);
917 }
918 }
919 }
920
921 int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
922 {
923 LPAPPLICATION_PAGE_LIST_ITEM Param1;
924 LPAPPLICATION_PAGE_LIST_ITEM Param2;
925
926 if (bSortAscending) {
927 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
928 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
929 } else {
930 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
931 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
932 }
933 return wcscmp(Param1->szTitle, Param2->szTitle);
934 }