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