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 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 noApps; 45 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam); 46 void AddOrUpdateHwnd(HWND hWnd, WCHAR *szTitle, HICON hIcon, BOOL bHung); 47 void ApplicationPageUpdate(void); 48 void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam); 49 void ApplicationPageShowContextMenu1(void); 50 void ApplicationPageShowContextMenu2(void); 51 int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 52 int ProcGetIndexByProcessId(DWORD dwProcessId); 53 54 #if 0 55 void SwitchToThisWindow ( 56 HWND hWnd, /* Handle to the window that should be activated */ 57 BOOL bRestore /* Restore the window if it is minimized */ 58 ); 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 INT_PTR CALLBACK 87 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 88 { 89 RECT rc; 90 int nXDifference; 91 int nYDifference; 92 LV_COLUMN column; 93 WCHAR szTemp[256]; 94 int cx, cy; 95 HANDLE hRefreshThread = NULL; 96 97 switch (message) { 98 case WM_INITDIALOG: 99 100 /* Save the width and height */ 101 GetClientRect(hDlg, &rc); 102 nApplicationPageWidth = rc.right; 103 nApplicationPageHeight = rc.bottom; 104 105 /* Update window position */ 106 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); 107 108 /* Get handles to the controls */ 109 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST); 110 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK); 111 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO); 112 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK); 113 114 SetWindowTextW(hApplicationPageListCtrl, L"Tasks"); 115 116 /* Initialize the application page's controls */ 117 column.mask = LVCF_TEXT|LVCF_WIDTH; 118 119 LoadStringW(hInst, IDS_TAB_TASK, szTemp, 256); 120 column.pszText = szTemp; 121 column.cx = 250; 122 (void)ListView_InsertColumn(hApplicationPageListCtrl, 0, &column); /* Add the "Task" column */ 123 column.mask = LVCF_TEXT|LVCF_WIDTH; 124 LoadStringW(hInst, IDS_TAB_STATUS, szTemp, 256); 125 column.pszText = szTemp; 126 column.cx = 95; 127 (void)ListView_InsertColumn(hApplicationPageListCtrl, 1, &column); /* Add the "Status" column */ 128 129 (void)ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(16, 16, GetSystemColorDepth()|ILC_MASK, 0, 1), LVSIL_SMALL); 130 (void)ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(32, 32, GetSystemColorDepth()|ILC_MASK, 0, 1), LVSIL_NORMAL); 131 132 UpdateApplicationListControlViewSetting(); 133 134 /* Start our refresh thread */ 135 hRefreshThread = CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL); 136 137 return TRUE; 138 139 case WM_DESTROY: 140 /* Close the event handle, this will make the */ 141 /* refresh thread exit when the wait fails */ 142 CloseHandle(hApplicationPageEvent); 143 CloseHandle(hRefreshThread); 144 break; 145 146 case WM_COMMAND: 147 148 /* Handle the button clicks */ 149 switch (LOWORD(wParam)) 150 { 151 case IDC_ENDTASK: 152 ApplicationPage_OnEndTask(); 153 break; 154 case IDC_SWITCHTO: 155 ApplicationPage_OnSwitchTo(); 156 break; 157 case IDC_NEWTASK: 158 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0); 159 break; 160 } 161 162 break; 163 164 case WM_SIZE: 165 if (wParam == SIZE_MINIMIZED) 166 return 0; 167 168 cx = LOWORD(lParam); 169 cy = HIWORD(lParam); 170 nXDifference = cx - nApplicationPageWidth; 171 nYDifference = cy - nApplicationPageHeight; 172 nApplicationPageWidth = cx; 173 nApplicationPageHeight = cy; 174 175 /* Reposition the application page's controls */ 176 GetWindowRect(hApplicationPageListCtrl, &rc); 177 cx = (rc.right - rc.left) + nXDifference; 178 cy = (rc.bottom - rc.top) + nYDifference; 179 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 180 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE); 181 182 GetClientRect(hApplicationPageEndTaskButton, &rc); 183 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(PRECT)(&rc), (sizeof(RECT)/sizeof(POINT)) ); 184 cx = rc.left + nXDifference; 185 cy = rc.top + nYDifference; 186 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); 187 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE); 188 189 GetClientRect(hApplicationPageSwitchToButton, &rc); 190 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(PRECT)(&rc), (sizeof(RECT)/sizeof(POINT)) ); 191 cx = rc.left + nXDifference; 192 cy = rc.top + nYDifference; 193 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); 194 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE); 195 196 GetClientRect(hApplicationPageNewTaskButton, &rc); 197 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(PRECT)(&rc), (sizeof(RECT)/sizeof(POINT)) ); 198 cx = rc.left + nXDifference; 199 cy = rc.top + nYDifference; 200 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); 201 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE); 202 203 break; 204 205 case WM_NOTIFY: 206 ApplicationPageOnNotify(wParam, lParam); 207 break; 208 209 } 210 211 return 0; 212 } 213 214 void RefreshApplicationPage(void) 215 { 216 /* Signal the event so that our refresh thread */ 217 /* will wake up and refresh the application page */ 218 SetEvent(hApplicationPageEvent); 219 } 220 221 void UpdateApplicationListControlViewSetting(void) 222 { 223 DWORD dwStyle = GetWindowLongPtrW(hApplicationPageListCtrl, GWL_STYLE); 224 225 dwStyle &= ~(LVS_REPORT | LVS_ICON | LVS_LIST | LVS_SMALLICON); 226 227 switch (TaskManagerSettings.ViewMode) { 228 case ID_VIEW_LARGE: dwStyle |= LVS_ICON; break; 229 case ID_VIEW_SMALL: dwStyle |= LVS_SMALLICON; break; 230 case ID_VIEW_DETAILS: dwStyle |= LVS_REPORT; break; 231 } 232 SetWindowLongPtrW(hApplicationPageListCtrl, GWL_STYLE, dwStyle); 233 234 RefreshApplicationPage(); 235 } 236 237 DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter) 238 { 239 INT i; 240 BOOL bItemRemoved = FALSE; 241 LV_ITEM item; 242 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 243 HIMAGELIST hImageListLarge; 244 HIMAGELIST hImageListSmall; 245 246 /* Create the event */ 247 hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL); 248 249 /* If we couldn't create the event then exit the thread */ 250 if (!hApplicationPageEvent) 251 return 0; 252 253 while (1) 254 { 255 DWORD dwWaitVal; 256 257 /* Wait on the event */ 258 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE); 259 260 /* If the wait failed then the event object must have been */ 261 /* closed and the task manager is exiting so exit this thread */ 262 if (dwWaitVal == WAIT_FAILED) 263 return 0; 264 265 if (dwWaitVal == WAIT_OBJECT_0) 266 { 267 /* Reset our event */ 268 ResetEvent(hApplicationPageEvent); 269 270 /* 271 * FIXME: 272 * 273 * Should this be EnumDesktopWindows() instead? 274 */ 275 noApps = TRUE; 276 EnumWindows(EnumWindowsProc, 0); 277 if (noApps) 278 (void)ListView_DeleteAllItems(hApplicationPageListCtrl); 279 280 /* Get the image lists */ 281 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL); 282 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL); 283 284 /* Check to see if we need to remove any items from the list */ 285 for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--) 286 { 287 memset(&item, 0, sizeof(LV_ITEM)); 288 item.mask = LVIF_IMAGE|LVIF_PARAM; 289 item.iItem = i; 290 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 291 292 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 293 if (!IsWindow(pAPLI->hWnd)|| 294 (wcslen(pAPLI->szTitle) <= 0) || 295 !IsWindowVisible(pAPLI->hWnd) || 296 (GetParent(pAPLI->hWnd) != NULL) || 297 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) || 298 (GetWindowLongPtr(pAPLI->hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) 299 { 300 ImageList_Remove(hImageListLarge, item.iItem); 301 ImageList_Remove(hImageListSmall, item.iItem); 302 303 (void)ListView_DeleteItem(hApplicationPageListCtrl, item.iItem); 304 HeapFree(GetProcessHeap(), 0, pAPLI); 305 bItemRemoved = TRUE; 306 } 307 } 308 309 /* 310 * If an item was removed from the list then 311 * we need to resync all the items with the 312 * image list 313 */ 314 if (bItemRemoved) 315 { 316 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) 317 { 318 memset(&item, 0, sizeof(LV_ITEM)); 319 item.mask = LVIF_IMAGE; 320 item.iItem = i; 321 item.iImage = i; 322 (void)ListView_SetItem(hApplicationPageListCtrl, &item); 323 } 324 bItemRemoved = FALSE; 325 } 326 327 ApplicationPageUpdate(); 328 } 329 } 330 } 331 332 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) 333 { 334 HICON hIcon; 335 WCHAR szText[260]; 336 BOOL bLargeIcon; 337 BOOL bHung = FALSE; 338 HICON* xhIcon = (HICON*)&hIcon; 339 340 typedef int (FAR __stdcall *IsHungAppWindowProc)(HWND); 341 IsHungAppWindowProc IsHungAppWindow; 342 343 344 /* Skip our window */ 345 if (hWnd == hMainWnd) 346 return TRUE; 347 348 bLargeIcon = (TaskManagerSettings.ViewMode == ID_VIEW_LARGE); 349 350 GetWindowTextW(hWnd, szText, 260); /* Get the window text */ 351 352 /* Check and see if this is a top-level app window */ 353 if ((wcslen(szText) <= 0) || 354 !IsWindowVisible(hWnd) || 355 (GetParent(hWnd) != NULL) || 356 (GetWindow(hWnd, GW_OWNER) != NULL) || 357 (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) 358 { 359 return TRUE; /* Skip this window */ 360 } 361 362 noApps = FALSE; 363 /* Get the icon for this window */ 364 hIcon = NULL; 365 SendMessageTimeoutW(hWnd, WM_GETICON,bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)xhIcon); 366 367 if (!hIcon) 368 { 369 hIcon = (HICON)(LONG_PTR)GetClassLongPtrW(hWnd, bLargeIcon ? GCL_HICON : GCL_HICONSM); 370 if (!hIcon) hIcon = (HICON)(LONG_PTR)GetClassLongPtrW(hWnd, bLargeIcon ? GCL_HICONSM : GCL_HICON); 371 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)xhIcon); 372 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)xhIcon); 373 } 374 375 if (!hIcon) 376 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM)); 377 378 bHung = FALSE; 379 380 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(L"USER32.DLL"), "IsHungAppWindow"); 381 382 if (IsHungAppWindow) 383 bHung = IsHungAppWindow(hWnd); 384 385 AddOrUpdateHwnd(hWnd, szText, hIcon, bHung); 386 387 return TRUE; 388 } 389 390 void AddOrUpdateHwnd(HWND hWnd, WCHAR *szTitle, HICON hIcon, BOOL bHung) 391 { 392 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; 393 HIMAGELIST hImageListLarge; 394 HIMAGELIST hImageListSmall; 395 LV_ITEM item; 396 int i; 397 BOOL bAlreadyInList = FALSE; 398 399 memset(&item, 0, sizeof(LV_ITEM)); 400 401 /* Get the image lists */ 402 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL); 403 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL); 404 405 /* Check to see if it's already in our list */ 406 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) 407 { 408 memset(&item, 0, sizeof(LV_ITEM)); 409 item.mask = LVIF_IMAGE|LVIF_PARAM; 410 item.iItem = i; 411 (void)ListView_GetItem(hApplicationPageListCtrl, &item); 412 413 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; 414 if (pAPLI->hWnd == hWnd) 415 { 416 bAlreadyInList = TRUE; 417 break; 418 } 419 } 420 421 /* If it is already in the list then update it if necessary */ 422 if (bAlreadyInList) 423 { 424 /* Check to see if anything needs updating */ 425 if ((pAPLI->hIcon != hIcon) || 426 (_wcsicmp(pAPLI->szTitle, szTitle) != 0) || 427 (pAPLI->bHung != bHung)) 428 { 429 /* Update the structure */ 430 pAPLI->hIcon = hIcon; 431 pAPLI->bHung = bHung; 432 wcscpy(pAPLI->szTitle, szTitle); 433 434 /* Update the image list */ 435 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon); 436 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon); 437 438 /* Update the list view */ 439 (void)ListView_RedrawItems(hApplicationPageListCtrl, 0, ListView_GetItemCount(hApplicationPageListCtrl)); 440 /* UpdateWindow(hApplicationPageListCtrl); */ 441 InvalidateRect(hApplicationPageListCtrl, NULL, 0); 442 } 443 } 444 /* It is not already in the list so add it */ 445 else 446 { 447 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM)); 448 449 pAPLI->hWnd = hWnd; 450 pAPLI->hIcon = hIcon; 451 pAPLI->bHung = bHung; 452 wcscpy(pAPLI->szTitle, szTitle); 453 454 /* Add the item to the list */ 455 memset(&item, 0, sizeof(LV_ITEM)); 456 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; 457 ImageList_AddIcon(hImageListLarge, hIcon); 458 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon); 459 item.pszText = LPSTR_TEXTCALLBACK; 460 item.iItem = ListView_GetItemCount(hApplicationPageListCtrl); 461 item.lParam = (LPARAM)pAPLI; 462 (void)ListView_InsertItem(hApplicationPageListCtrl, &item); 463 } 464 return; 465 } 466 467 void ApplicationPageUpdate(void) 468 { 469 /* Enable or disable the "End Task" & "Switch To" buttons */ 470 if (ListView_GetSelectedCount(hApplicationPageListCtrl)) 471 { 472 EnableWindow(hApplicationPageEndTaskButton, TRUE); 473 } 474 else 475 { 476 EnableWindow(hApplicationPageEndTaskButton, FALSE); 477 } 478 /* Enable "Switch To" button only if one app is selected */ 479 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1 ) 480 { 481 EnableWindow(hApplicationPageSwitchToButton, TRUE); 482 } 483 else 484 { 485 EnableWindow(hApplicationPageSwitchToButton, FALSE); 486 } 487 488 /* If we are on the applications tab the windows menu will be */ 489 /* present on the menu bar so enable & disable the menu items */ 490 if (TabCtrl_GetCurSel(hTabWnd) == 0) 491 { 492 HMENU hMenu; 493 HMENU hWindowsMenu; 494 495 hMenu = GetMenu(hMainWnd); 496 hWindowsMenu = GetSubMenu(hMenu, 3); 497 498 /* Only one item selected */ 499 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1) 500 { 501 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 502 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 503 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); 504 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); 505 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 506 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED); 507 } 508 /* More than one item selected */ 509 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1) 510 { 511 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED); 512 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED); 513 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); 514 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); 515 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED); 516 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 517 } 518 /* No items selected */ 519 else 520 { 521 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 522 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 523 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 524 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 525 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 526 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); 527 } 528 } 529 } 530 531 void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam) 532 { 533 int idctrl; 534 LPNMHDR pnmh; 535 LPNM_LISTVIEW pnmv; 536 LV_DISPINFO* pnmdi; 537 LPAPPLICATION_PAGE_LIST_ITEM pAPLI; 538 WCHAR szMsg[256]; 539 540 541 idctrl = (int) wParam; 542 pnmh = (LPNMHDR) lParam; 543 pnmv = (LPNM_LISTVIEW) lParam; 544 pnmdi = (LV_DISPINFO*) lParam; 545 546 if (pnmh->hwndFrom == hApplicationPageListCtrl) { 547 switch (pnmh->code) { 548 case LVN_ITEMCHANGED: 549 ApplicationPageUpdate(); 550 break; 551 552 case LVN_GETDISPINFO: 553 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam; 554 555 /* Update the item text */ 556 if (pnmdi->item.iSubItem == 0) 557 { 558 wcsncpy(pnmdi->item.pszText, pAPLI->szTitle, pnmdi->item.cchTextMax); 559 } 560 561 /* Update the item status */ 562 else if (pnmdi->item.iSubItem == 1) 563 { 564 if (pAPLI->bHung) 565 { 566 LoadStringW( GetModuleHandleW(NULL), IDS_Not_Responding , szMsg, sizeof(szMsg) / sizeof(szMsg[0])); 567 } 568 else 569 { 570 LoadStringW( GetModuleHandleW(NULL), IDS_Running, (LPWSTR) szMsg, sizeof(szMsg) / sizeof(szMsg[0])); 571 } 572 wcsncpy(pnmdi->item.pszText, szMsg, pnmdi->item.cchTextMax); 573 } 574 575 break; 576 577 case NM_RCLICK: 578 579 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1) 580 { 581 ApplicationPageShowContextMenu1(); 582 } 583 else 584 { 585 ApplicationPageShowContextMenu2(); 586 } 587 588 break; 589 590 case NM_DBLCLK: 591 592 ApplicationPage_OnSwitchTo(); 593 594 break; 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