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