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 LPNMHDR pnmh; 531 LV_DISPINFO* pnmdi; 532 LPAPPLICATION_PAGE_LIST_ITEM pAPLI; 533 WCHAR szMsg[256]; 534 535 pnmh = (LPNMHDR) 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 case LVN_KEYDOWN: 589 590 if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE) 591 ApplicationPage_OnEndTask(); 592 593 break; 594 595 } 596 } 597 else if (pnmh->hwndFrom == ListView_GetHeader(hApplicationPageListCtrl)) 598 { 599 switch (pnmh->code) 600 { 601 case NM_RCLICK: 602 603 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1) 604 { 605 ApplicationPageShowContextMenu1(); 606 } 607 else 608 { 609 ApplicationPageShowContextMenu2(); 610 } 611 612 break; 613 614 case HDN_ITEMCLICK: 615 616 (void)ListView_SortItems(hApplicationPageListCtrl, ApplicationPageCompareFunc, 0); 617 bSortAscending = !bSortAscending; 618 619 break; 620 } 621 } 622 623 } 624 625 void ApplicationPageShowContextMenu1(void) 626 { 627 HMENU hMenu; 628 HMENU hSubMenu; 629 POINT pt; 630 631 GetCursorPos(&pt); 632 633 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1)); 634 hSubMenu = GetSubMenu(hMenu, 0); 635 636 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND); 637 638 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL); 639 640 DestroyMenu(hMenu); 641 } 642 643 void ApplicationPageShowContextMenu2(void) 644 { 645 HMENU hMenu; 646 HMENU hSubMenu; 647 POINT pt; 648 649 GetCursorPos(&pt); 650 651 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2)); 652 hSubMenu = GetSubMenu(hMenu, 0); 653 654 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1) 655 { 656 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 657 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 658 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); 659 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); 660 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 661 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED); 662 } 663 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1) 664 { 665 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED); 666 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED); 667 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); 668 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); 669 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED); 670 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 671 } 672 else 673 { 674 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 675 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 676 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 677 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 678 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 679 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 680 } 681 682 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND); 683 684 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL); 685 686 DestroyMenu(hMenu); 687 } 688 689 void ApplicationPage_OnView(DWORD dwMode) 690 { 691 HMENU hMenu; 692 HMENU hViewMenu; 693 694 hMenu = GetMenu(hMainWnd); 695 hViewMenu = GetSubMenu(hMenu, 2); 696 697 TaskManagerSettings.ViewMode = dwMode; 698 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, dwMode, MF_BYCOMMAND); 699 700 UpdateApplicationListControlViewSetting(); 701 } 702 703 void ApplicationPage_OnWindowsTile(DWORD dwMode) 704 { 705 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 706 LV_ITEM item; 707 int i; 708 HWND* hWndArray; 709 int nWndCount; 710 711 hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl)); 712 nWndCount = 0; 713 714 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { 715 memset(&item, 0, sizeof(LV_ITEM)); 716 item.mask = LVIF_STATE|LVIF_PARAM; 717 item.iItem = i; 718 item.stateMask = (UINT)-1; 719 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 720 721 if (item.state & LVIS_SELECTED) { 722 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 723 if (pAPLI) { 724 hWndArray[nWndCount] = pAPLI->hWnd; 725 nWndCount++; 726 } 727 } 728 } 729 730 TileWindows(NULL, dwMode, NULL, nWndCount, hWndArray); 731 HeapFree(GetProcessHeap(), 0, hWndArray); 732 } 733 734 void ApplicationPage_OnWindowsMinimize(void) 735 { 736 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 737 LV_ITEM item; 738 int i; 739 740 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { 741 memset(&item, 0, sizeof(LV_ITEM)); 742 item.mask = LVIF_STATE|LVIF_PARAM; 743 item.iItem = i; 744 item.stateMask = (UINT)-1; 745 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 746 if (item.state & LVIS_SELECTED) { 747 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 748 if (pAPLI) { 749 ShowWindow(pAPLI->hWnd, SW_MINIMIZE); 750 } 751 } 752 } 753 } 754 755 void ApplicationPage_OnWindowsMaximize(void) 756 { 757 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 758 LV_ITEM item; 759 int i; 760 761 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { 762 memset(&item, 0, sizeof(LV_ITEM)); 763 item.mask = LVIF_STATE|LVIF_PARAM; 764 item.iItem = i; 765 item.stateMask = (UINT)-1; 766 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 767 if (item.state & LVIS_SELECTED) { 768 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 769 if (pAPLI) { 770 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE); 771 } 772 } 773 } 774 } 775 776 void ApplicationPage_OnWindowsCascade(void) 777 { 778 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 779 LV_ITEM item; 780 int i; 781 HWND* hWndArray; 782 int nWndCount; 783 784 hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl)); 785 nWndCount = 0; 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 if (item.state & LVIS_SELECTED) { 794 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 795 if (pAPLI) { 796 hWndArray[nWndCount] = pAPLI->hWnd; 797 nWndCount++; 798 } 799 } 800 } 801 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray); 802 HeapFree(GetProcessHeap(), 0, hWndArray); 803 } 804 805 void ApplicationPage_OnWindowsBringToFront(void) 806 { 807 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 808 LV_ITEM item; 809 int i; 810 811 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { 812 memset(&item, 0, sizeof(LV_ITEM)); 813 item.mask = LVIF_STATE|LVIF_PARAM; 814 item.iItem = i; 815 item.stateMask = (UINT)-1; 816 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 817 if (item.state & LVIS_SELECTED) { 818 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 819 break; 820 } 821 } 822 if (pAPLI) { 823 if (IsIconic(pAPLI->hWnd)) 824 ShowWindow(pAPLI->hWnd, SW_RESTORE); 825 BringWindowToTop(pAPLI->hWnd); 826 } 827 } 828 829 void ApplicationPage_OnSwitchTo(void) 830 { 831 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 832 LV_ITEM item; 833 int i; 834 835 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { 836 memset(&item, 0, sizeof(LV_ITEM)); 837 item.mask = LVIF_STATE|LVIF_PARAM; 838 item.iItem = i; 839 item.stateMask = (UINT)-1; 840 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 841 842 if (item.state & LVIS_SELECTED) { 843 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 844 break; 845 } 846 } 847 if (pAPLI) { 848 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL); 849 PROCSWITCHTOTHISWINDOW SwitchToThisWindow; 850 851 HMODULE hUser32 = GetModuleHandleW(L"USER32"); 852 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow"); 853 if (SwitchToThisWindow) { 854 SwitchToThisWindow(pAPLI->hWnd, TRUE); 855 } else { 856 if (IsIconic(pAPLI->hWnd)) 857 ShowWindow(pAPLI->hWnd, SW_RESTORE); 858 BringWindowToTop(pAPLI->hWnd); 859 SetForegroundWindow(pAPLI->hWnd); 860 } 861 if (TaskManagerSettings.MinimizeOnUse) 862 ShowWindow(hMainWnd, SW_MINIMIZE); 863 } 864 } 865 866 void ApplicationPage_OnEndTask(void) 867 { 868 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 869 LV_ITEM item; 870 int i; 871 872 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { 873 memset(&item, 0, sizeof(LV_ITEM)); 874 item.mask = LVIF_STATE|LVIF_PARAM; 875 item.iItem = i; 876 item.stateMask = (UINT)-1; 877 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 878 if (item.state & LVIS_SELECTED) { 879 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 880 if (pAPLI) { 881 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0); 882 } 883 } 884 } 885 } 886 887 void ApplicationPage_OnGotoProcess(void) 888 { 889 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 890 LV_ITEM item; 891 int i; 892 893 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { 894 memset(&item, 0, sizeof(LV_ITEM)); 895 item.mask = LVIF_STATE|LVIF_PARAM; 896 item.iItem = i; 897 item.stateMask = (UINT)-1; 898 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 899 if (item.state & LVIS_SELECTED) { 900 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 901 break; 902 } 903 } 904 if (pAPLI) { 905 DWORD dwProcessId; 906 907 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId); 908 /* 909 * Switch to the process tab 910 */ 911 TabCtrl_SetCurFocus(hTabWnd, 1); 912 /* 913 * Select the process item in the list 914 */ 915 i = ProcGetIndexByProcessId(dwProcessId); 916 if (i != -1) 917 { 918 ListView_SetItemState(hProcessPageListCtrl, 919 i, 920 LVIS_SELECTED | LVIS_FOCUSED, 921 LVIS_SELECTED | LVIS_FOCUSED); 922 (void)ListView_EnsureVisible(hProcessPageListCtrl, 923 i, 924 FALSE); 925 } 926 } 927 } 928 929 int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) 930 { 931 LPAPPLICATION_PAGE_LIST_ITEM Param1; 932 LPAPPLICATION_PAGE_LIST_ITEM Param2; 933 934 if (bSortAscending) { 935 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1; 936 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2; 937 } else { 938 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2; 939 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1; 940 } 941 return wcscmp(Param1->szTitle, Param2->szTitle); 942 } 943