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