1 /* 2 * ReactOS Task Manager 3 * 4 * taskmgr.c : Defines the entry point for the application. 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 #include "perfpage.h" 27 #include "about.h" 28 #include "affinity.h" 29 #include "debug.h" 30 #include "priority.h" 31 32 #define STATUS_WINDOW 2001 33 34 /* Global Variables: */ 35 HINSTANCE hInst; /* current instance */ 36 37 HWND hMainWnd; /* Main Window */ 38 HWND hStatusWnd; /* Status Bar Window */ 39 HWND hTabWnd; /* Tab Control Window */ 40 41 HMENU hWindowMenu = NULL; 42 43 int nMinimumWidth; /* Minimum width of the dialog (OnSize()'s cx) */ 44 int nMinimumHeight; /* Minimum height of the dialog (OnSize()'s cy) */ 45 46 int nOldWidth; /* Holds the previous client area width */ 47 int nOldHeight; /* Holds the previous client area height */ 48 49 BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */ 50 BOOL bWasKeyboardInput = FALSE; /* TabChange by Keyboard or Mouse ? */ 51 52 TASKMANAGER_SETTINGS TaskManagerSettings; 53 54 //////////////////////////////////////////////////////////////////////////////// 55 // Taken from WinSpy++ 1.7 56 // http://www.catch22.net/software/winspy 57 // Copyright (c) 2002 by J Brown 58 // 59 60 // 61 // Copied from uxtheme.h 62 // If you have this new header, then delete these and 63 // #include <uxtheme.h> instead! 64 // 65 #define ETDT_DISABLE 0x00000001 66 #define ETDT_ENABLE 0x00000002 67 #define ETDT_USETABTEXTURE 0x00000004 68 #define ETDT_ENABLETAB (ETDT_ENABLE | ETDT_USETABTEXTURE) 69 70 // 71 typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD); 72 73 // 74 // Try to call EnableThemeDialogTexture, if uxtheme.dll is present 75 // 76 BOOL EnableDialogTheme(HWND hwnd) 77 { 78 HMODULE hUXTheme; 79 ETDTProc fnEnableThemeDialogTexture; 80 81 hUXTheme = LoadLibraryA("uxtheme.dll"); 82 83 if(hUXTheme) 84 { 85 fnEnableThemeDialogTexture = 86 (ETDTProc)GetProcAddress(hUXTheme, "EnableThemeDialogTexture"); 87 88 if(fnEnableThemeDialogTexture) 89 { 90 fnEnableThemeDialogTexture(hwnd, ETDT_ENABLETAB); 91 92 FreeLibrary(hUXTheme); 93 return TRUE; 94 } 95 else 96 { 97 // Failed to locate API! 98 FreeLibrary(hUXTheme); 99 return FALSE; 100 } 101 } 102 else 103 { 104 // Not running under XP? Just fail gracefully 105 return FALSE; 106 } 107 } 108 109 int APIENTRY wWinMain(HINSTANCE hInstance, 110 HINSTANCE hPrevInstance, 111 LPWSTR lpCmdLine, 112 int nCmdShow) 113 { 114 HANDLE hProcess; 115 HANDLE hToken; 116 TOKEN_PRIVILEGES tkp; 117 HANDLE hMutex; 118 119 /* check wether we're already running or not */ 120 hMutex = CreateMutexW(NULL, TRUE, L"taskmgrros"); 121 if (hMutex && GetLastError() == ERROR_ALREADY_EXISTS) 122 { 123 /* Restore existing taskmanager and bring window to front */ 124 /* Relies on the fact that the application title string and window title are the same */ 125 HWND hTaskMgr; 126 TCHAR szTaskmgr[128]; 127 128 LoadString(hInst, IDS_APP_TITLE, szTaskmgr, sizeof(szTaskmgr)/sizeof(TCHAR)); 129 hTaskMgr = FindWindow(NULL, szTaskmgr); 130 131 if (hTaskMgr != NULL) 132 { 133 SendMessage(hTaskMgr, WM_SYSCOMMAND, SC_RESTORE, 0); 134 SetForegroundWindow(hTaskMgr); 135 } 136 137 CloseHandle(hMutex); 138 return 0; 139 } 140 else if (!hMutex) 141 { 142 return 1; 143 } 144 145 /* Initialize global variables */ 146 hInst = hInstance; 147 148 /* Change our priority class to HIGH */ 149 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); 150 SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS); 151 CloseHandle(hProcess); 152 153 /* Now lets get the SE_DEBUG_NAME privilege 154 * so that we can debug processes 155 */ 156 157 /* Get a token for this process. */ 158 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 159 { 160 /* Get the LUID for the debug privilege. */ 161 if (LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid)) 162 { 163 tkp.PrivilegeCount = 1; /* one privilege to set */ 164 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 165 166 /* Get the debug privilege for this process. */ 167 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 168 } 169 CloseHandle(hToken); 170 } 171 172 /* Load our settings from the registry */ 173 LoadSettings(); 174 175 /* Initialize perf data */ 176 if (!PerfDataInitialize()) 177 { 178 return -1; 179 } 180 181 /* 182 * Set our shutdown parameters: we want to shutdown the very last, 183 * without displaying any end task dialog if needed. 184 */ 185 SetProcessShutdownParameters(1, SHUTDOWN_NORETRY); 186 187 DialogBoxW(hInst, (LPCWSTR)IDD_TASKMGR_DIALOG, NULL, TaskManagerWndProc); 188 189 /* Save our settings to the registry */ 190 SaveSettings(); 191 PerfDataUninitialize(); 192 CloseHandle(hMutex); 193 if (hWindowMenu) 194 DestroyMenu(hWindowMenu); 195 return 0; 196 } 197 198 /* Message handler for dialog box. */ 199 INT_PTR CALLBACK 200 TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 201 { 202 #if 0 203 HDC hdc; 204 PAINTSTRUCT ps; 205 RECT rc; 206 #endif 207 LPRECT pRC; 208 LPNMHDR pnmh; 209 WINDOWPLACEMENT wp; 210 211 switch (message) { 212 case WM_INITDIALOG: 213 // For now, the Help dialog menu item is disabled because of lacking of HTML Help support 214 EnableMenuItem(GetMenu(hDlg), ID_HELP_TOPICS, MF_BYCOMMAND | MF_GRAYED); 215 hMainWnd = hDlg; 216 return OnCreate(hDlg); 217 218 case WM_COMMAND: 219 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { 220 EndDialog(hDlg, LOWORD(wParam)); 221 return TRUE; 222 } 223 /* Process menu commands */ 224 switch (LOWORD(wParam)) 225 { 226 case ID_FILE_NEW: 227 TaskManager_OnFileNew(); 228 break; 229 case ID_OPTIONS_ALWAYSONTOP: 230 TaskManager_OnOptionsAlwaysOnTop(); 231 break; 232 case ID_OPTIONS_MINIMIZEONUSE: 233 TaskManager_OnOptionsMinimizeOnUse(); 234 break; 235 case ID_OPTIONS_HIDEWHENMINIMIZED: 236 TaskManager_OnOptionsHideWhenMinimized(); 237 break; 238 case ID_OPTIONS_SHOW16BITTASKS: 239 TaskManager_OnOptionsShow16BitTasks(); 240 break; 241 case ID_RESTORE: 242 TaskManager_OnRestoreMainWindow(); 243 break; 244 case ID_VIEW_LARGE: 245 case ID_VIEW_SMALL: 246 case ID_VIEW_DETAILS: 247 ApplicationPage_OnView(LOWORD(wParam)); 248 break; 249 case ID_VIEW_SHOWKERNELTIMES: 250 PerformancePage_OnViewShowKernelTimes(); 251 break; 252 case ID_VIEW_CPUHISTORY_ONEGRAPHALL: 253 PerformancePage_OnViewCPUHistoryOneGraphAll(); 254 break; 255 case ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU: 256 PerformancePage_OnViewCPUHistoryOneGraphPerCPU(); 257 break; 258 case ID_VIEW_UPDATESPEED_HIGH: 259 case ID_VIEW_UPDATESPEED_NORMAL: 260 case ID_VIEW_UPDATESPEED_LOW: 261 case ID_VIEW_UPDATESPEED_PAUSED: 262 TaskManager_OnViewUpdateSpeed(LOWORD(wParam)); 263 break; 264 case ID_VIEW_SELECTCOLUMNS: 265 ProcessPage_OnViewSelectColumns(); 266 break; 267 case ID_VIEW_REFRESH: 268 PostMessageW(hDlg, WM_TIMER, 0, 0); 269 break; 270 case ID_WINDOWS_TILEHORIZONTALLY: 271 ApplicationPage_OnWindowsTile(MDITILE_HORIZONTAL); 272 break; 273 case ID_WINDOWS_TILEVERTICALLY: 274 ApplicationPage_OnWindowsTile(MDITILE_VERTICAL); 275 break; 276 case ID_WINDOWS_MINIMIZE: 277 ApplicationPage_OnWindowsMinimize(); 278 break; 279 case ID_WINDOWS_MAXIMIZE: 280 ApplicationPage_OnWindowsMaximize(); 281 break; 282 case ID_WINDOWS_CASCADE: 283 ApplicationPage_OnWindowsCascade(); 284 break; 285 case ID_WINDOWS_BRINGTOFRONT: 286 ApplicationPage_OnWindowsBringToFront(); 287 break; 288 case ID_APPLICATION_PAGE_SWITCHTO: 289 ApplicationPage_OnSwitchTo(); 290 break; 291 case ID_APPLICATION_PAGE_ENDTASK: 292 ApplicationPage_OnEndTask(); 293 break; 294 case ID_APPLICATION_PAGE_GOTOPROCESS: 295 ApplicationPage_OnGotoProcess(); 296 break; 297 case ID_PROCESS_PAGE_ENDPROCESS: 298 ProcessPage_OnEndProcess(); 299 break; 300 case ID_PROCESS_PAGE_ENDPROCESSTREE: 301 ProcessPage_OnEndProcessTree(); 302 break; 303 case ID_PROCESS_PAGE_DEBUG: 304 ProcessPage_OnDebug(); 305 break; 306 case ID_PROCESS_PAGE_SETAFFINITY: 307 ProcessPage_OnSetAffinity(); 308 break; 309 case ID_PROCESS_PAGE_SETPRIORITY_REALTIME: 310 DoSetPriority(REALTIME_PRIORITY_CLASS); 311 break; 312 case ID_PROCESS_PAGE_SETPRIORITY_HIGH: 313 DoSetPriority(HIGH_PRIORITY_CLASS); 314 break; 315 case ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL: 316 DoSetPriority(ABOVE_NORMAL_PRIORITY_CLASS); 317 break; 318 case ID_PROCESS_PAGE_SETPRIORITY_NORMAL: 319 DoSetPriority(NORMAL_PRIORITY_CLASS); 320 break; 321 case ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL: 322 DoSetPriority(BELOW_NORMAL_PRIORITY_CLASS); 323 break; 324 case ID_PROCESS_PAGE_SETPRIORITY_LOW: 325 DoSetPriority(IDLE_PRIORITY_CLASS); 326 break; 327 328 /* ShutDown items */ 329 case ID_SHUTDOWN_STANDBY: 330 ShutDown_StandBy(); 331 break; 332 case ID_SHUTDOWN_HIBERNATE: 333 ShutDown_Hibernate(); 334 break; 335 case ID_SHUTDOWN_POWEROFF: 336 ShutDown_PowerOff(); 337 break; 338 case ID_SHUTDOWN_REBOOT: 339 ShutDown_Reboot(); 340 break; 341 case ID_SHUTDOWN_LOGOFF: 342 ShutDown_LogOffUser(); 343 break; 344 case ID_SHUTDOWN_SWITCHUSER: 345 ShutDown_SwitchUser(); 346 break; 347 case ID_SHUTDOWN_LOCKCOMPUTER: 348 ShutDown_LockComputer(); 349 break; 350 case ID_SHUTDOWN_DISCONNECT: 351 ShutDown_Disconnect(); 352 break; 353 case ID_SHUTDOWN_EJECT_COMPUTER: 354 ShutDown_EjectComputer(); 355 break; 356 357 case ID_HELP_ABOUT: 358 OnAbout(); 359 break; 360 case ID_FILE_EXIT: 361 EndDialog(hDlg, IDOK); 362 break; 363 } 364 break; 365 366 case WM_ONTRAYICON: 367 switch(lParam) 368 { 369 case WM_RBUTTONDOWN: 370 { 371 POINT pt; 372 BOOL OnTop; 373 HMENU hMenu, hPopupMenu; 374 375 GetCursorPos(&pt); 376 377 OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0); 378 379 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_TRAY_POPUP)); 380 hPopupMenu = GetSubMenu(hMenu, 0); 381 382 if(IsWindowVisible(hMainWnd)) 383 { 384 DeleteMenu(hPopupMenu, ID_RESTORE, MF_BYCOMMAND); 385 } 386 else 387 { 388 SetMenuDefaultItem(hPopupMenu, ID_RESTORE, FALSE); 389 } 390 391 if(OnTop) 392 { 393 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_CHECKED); 394 } else 395 { 396 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_UNCHECKED); 397 } 398 399 SetForegroundWindow(hMainWnd); 400 TrackPopupMenuEx(hPopupMenu, 0, pt.x, pt.y, hMainWnd, NULL); 401 402 DestroyMenu(hMenu); 403 break; 404 } 405 case WM_LBUTTONDBLCLK: 406 TaskManager_OnRestoreMainWindow(); 407 break; 408 } 409 break; 410 411 case WM_NOTIFY: 412 pnmh = (LPNMHDR)lParam; 413 if ((pnmh->hwndFrom == hTabWnd) && 414 (pnmh->idFrom == IDC_TAB)) 415 { 416 switch (pnmh->code) 417 { 418 case TCN_SELCHANGE: 419 TaskManager_OnTabWndSelChange(); 420 break; 421 case TCN_KEYDOWN: 422 bWasKeyboardInput = TRUE; 423 break; 424 case NM_CLICK: 425 bWasKeyboardInput = FALSE; 426 break; 427 } 428 } 429 break; 430 #if 0 431 case WM_NCPAINT: 432 hdc = GetDC(hDlg); 433 GetClientRect(hDlg, &rc); 434 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT)); 435 ReleaseDC(hDlg, hdc); 436 break; 437 438 case WM_PAINT: 439 hdc = BeginPaint(hDlg, &ps); 440 GetClientRect(hDlg, &rc); 441 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT)); 442 EndPaint(hDlg, &ps); 443 break; 444 #endif 445 case WM_SIZING: 446 /* Make sure the user is sizing the dialog */ 447 /* in an acceptable range */ 448 pRC = (LPRECT)lParam; 449 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) { 450 /* If the width is too small enlarge it to the minimum */ 451 if (nMinimumWidth > (pRC->right - pRC->left)) 452 pRC->left = pRC->right - nMinimumWidth; 453 } else { 454 /* If the width is too small enlarge it to the minimum */ 455 if (nMinimumWidth > (pRC->right - pRC->left)) 456 pRC->right = pRC->left + nMinimumWidth; 457 } 458 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) { 459 /* If the height is too small enlarge it to the minimum */ 460 if (nMinimumHeight > (pRC->bottom - pRC->top)) 461 pRC->top = pRC->bottom - nMinimumHeight; 462 } else { 463 /* If the height is too small enlarge it to the minimum */ 464 if (nMinimumHeight > (pRC->bottom - pRC->top)) 465 pRC->bottom = pRC->top + nMinimumHeight; 466 } 467 return TRUE; 468 break; 469 470 case WM_SIZE: 471 /* Handle the window sizing in it's own function */ 472 OnSize(wParam, LOWORD(lParam), HIWORD(lParam)); 473 break; 474 475 case WM_MOVE: 476 /* Handle the window moving in it's own function */ 477 OnMove(wParam, LOWORD(lParam), HIWORD(lParam)); 478 break; 479 480 case WM_DESTROY: 481 ShowWindow(hDlg, SW_HIDE); 482 TrayIcon_ShellRemoveTrayIcon(); 483 wp.length = sizeof(WINDOWPLACEMENT); 484 GetWindowPlacement(hDlg, &wp); 485 TaskManagerSettings.Left = wp.rcNormalPosition.left; 486 TaskManagerSettings.Top = wp.rcNormalPosition.top; 487 TaskManagerSettings.Right = wp.rcNormalPosition.right; 488 TaskManagerSettings.Bottom = wp.rcNormalPosition.bottom; 489 if (IsZoomed(hDlg) || (wp.flags & WPF_RESTORETOMAXIMIZED)) 490 TaskManagerSettings.Maximized = TRUE; 491 else 492 TaskManagerSettings.Maximized = FALSE; 493 /* Get rid of the allocated command line cache, if any */ 494 PerfDataDeallocCommandLineCache(); 495 if (hWindowMenu) 496 DestroyMenu(hWindowMenu); 497 return DefWindowProcW(hDlg, message, wParam, lParam); 498 499 case WM_TIMER: 500 /* Refresh the performance data */ 501 PerfDataRefresh(); 502 RefreshApplicationPage(); 503 RefreshProcessPage(); 504 RefreshPerformancePage(); 505 TrayIcon_ShellUpdateTrayIcon(); 506 break; 507 508 case WM_ENTERMENULOOP: 509 TaskManager_OnEnterMenuLoop(hDlg); 510 break; 511 case WM_EXITMENULOOP: 512 TaskManager_OnExitMenuLoop(hDlg); 513 break; 514 case WM_MENUSELECT: 515 TaskManager_OnMenuSelect(hDlg, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam); 516 break; 517 case WM_SYSCOLORCHANGE: 518 /* Forward WM_SYSCOLORCHANGE to common controls */ 519 SendMessage(hApplicationPageListCtrl, WM_SYSCOLORCHANGE, 0, 0); 520 SendMessage(hProcessPageListCtrl, WM_SYSCOLORCHANGE, 0, 0); 521 SendMessage(hProcessPageHeaderCtrl, WM_SYSCOLORCHANGE, 0, 0); 522 break; 523 } 524 525 return 0; 526 } 527 528 void FillSolidRect(HDC hDC, LPCRECT lpRect, COLORREF clr) 529 { 530 SetBkColor(hDC, clr); 531 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); 532 } 533 534 void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr) 535 { 536 RECT rect; 537 538 SetBkColor(hDC, clr); 539 rect.left = x; 540 rect.top = y; 541 rect.right = x + cx; 542 rect.bottom = y + cy; 543 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); 544 } 545 546 void Draw3dRect(HDC hDC, int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight) 547 { 548 FillSolidRect2(hDC, x, y, cx - 1, 1, clrTopLeft); 549 FillSolidRect2(hDC, x, y, 1, cy - 1, clrTopLeft); 550 FillSolidRect2(hDC, x + cx, y, -1, cy, clrBottomRight); 551 FillSolidRect2(hDC, x, y + cy, cx, -1, clrBottomRight); 552 } 553 554 void Draw3dRect2(HDC hDC, LPRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight) 555 { 556 Draw3dRect(hDC, lpRect->left, lpRect->top, lpRect->right - lpRect->left, 557 lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight); 558 } 559 560 static void SetUpdateSpeed(HWND hWnd) 561 { 562 /* Setup update speed (pause=fall down) */ 563 switch (TaskManagerSettings.UpdateSpeed) { 564 case ID_VIEW_UPDATESPEED_HIGH: 565 SetTimer(hWnd, 1, 1000, NULL); 566 break; 567 case ID_VIEW_UPDATESPEED_NORMAL: 568 SetTimer(hWnd, 1, 2000, NULL); 569 break; 570 case ID_VIEW_UPDATESPEED_LOW: 571 SetTimer(hWnd, 1, 4000, NULL); 572 break; 573 } 574 } 575 576 BOOL OnCreate(HWND hWnd) 577 { 578 HMENU hMenu; 579 HMENU hEditMenu; 580 HMENU hViewMenu; 581 HMENU hShutMenu; 582 HMENU hUpdateSpeedMenu; 583 HMENU hCPUHistoryMenu; 584 int nActivePage; 585 int nParts[3]; 586 RECT rc; 587 WCHAR szTemp[256]; 588 WCHAR szLogOffItem[MAX_PATH]; 589 LPWSTR lpUserName; 590 TCITEM item; 591 DWORD len = 0; 592 593 SendMessageW(hMainWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_TASKMANAGER))); 594 595 /* Initialize the Windows Common Controls DLL */ 596 InitCommonControls(); 597 598 /* Get the minimum window sizes */ 599 GetWindowRect(hWnd, &rc); 600 nMinimumWidth = (rc.right - rc.left); 601 nMinimumHeight = (rc.bottom - rc.top); 602 603 /* Create the status bar */ 604 hStatusWnd = CreateStatusWindow(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS, L"", hWnd, STATUS_WINDOW); 605 if(!hStatusWnd) 606 return FALSE; 607 608 /* Create the status bar panes */ 609 nParts[0] = STATUS_SIZE1; 610 nParts[1] = STATUS_SIZE2; 611 nParts[2] = STATUS_SIZE3; 612 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts); 613 614 /* Create tab pages */ 615 hTabWnd = GetDlgItem(hWnd, IDC_TAB); 616 #if 1 617 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hWnd, ApplicationPageWndProc); EnableDialogTheme(hApplicationPage); 618 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hWnd, ProcessPageWndProc); EnableDialogTheme(hProcessPage); 619 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hWnd, PerformancePageWndProc); EnableDialogTheme(hPerformancePage); 620 #else 621 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hTabWnd, ApplicationPageWndProc); EnableDialogTheme(hApplicationPage); 622 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hTabWnd, ProcessPageWndProc); EnableDialogTheme(hProcessPage); 623 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hTabWnd, PerformancePageWndProc); EnableDialogTheme(hPerformancePage); 624 #endif 625 626 /* Insert tabs */ 627 LoadStringW(hInst, IDS_TAB_APPS, szTemp, 256); 628 memset(&item, 0, sizeof(TCITEM)); 629 item.mask = TCIF_TEXT; 630 item.pszText = szTemp; 631 (void)TabCtrl_InsertItem(hTabWnd, 0, &item); 632 LoadStringW(hInst, IDS_TAB_PROCESSES, szTemp, 256); 633 memset(&item, 0, sizeof(TCITEM)); 634 item.mask = TCIF_TEXT; 635 item.pszText = szTemp; 636 (void)TabCtrl_InsertItem(hTabWnd, 1, &item); 637 LoadStringW(hInst, IDS_TAB_PERFORMANCE, szTemp, 256); 638 memset(&item, 0, sizeof(TCITEM)); 639 item.mask = TCIF_TEXT; 640 item.pszText = szTemp; 641 (void)TabCtrl_InsertItem(hTabWnd, 2, &item); 642 643 /* Size everything correctly */ 644 GetClientRect(hWnd, &rc); 645 nOldWidth = rc.right; 646 nOldHeight = rc.bottom; 647 /* nOldStartX = rc.left; */ 648 /*nOldStartY = rc.top; */ 649 650 #define PAGE_OFFSET_LEFT 17 651 #define PAGE_OFFSET_TOP 72 652 #define PAGE_OFFSET_WIDTH (PAGE_OFFSET_LEFT*2) 653 #define PAGE_OFFSET_HEIGHT (PAGE_OFFSET_TOP+32) 654 655 if ((TaskManagerSettings.Left != 0) || 656 (TaskManagerSettings.Top != 0) || 657 (TaskManagerSettings.Right != 0) || 658 (TaskManagerSettings.Bottom != 0)) 659 { 660 MoveWindow(hWnd, TaskManagerSettings.Left, TaskManagerSettings.Top, TaskManagerSettings.Right - TaskManagerSettings.Left, TaskManagerSettings.Bottom - TaskManagerSettings.Top, TRUE); 661 #ifdef __GNUC__TEST__ 662 MoveWindow(hApplicationPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE); 663 MoveWindow(hProcessPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE); 664 MoveWindow(hPerformancePage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE); 665 #endif 666 } 667 if (TaskManagerSettings.Maximized) 668 ShowWindow(hWnd, SW_MAXIMIZE); 669 670 /* Set the always on top style */ 671 hMenu = GetMenu(hWnd); 672 hEditMenu = GetSubMenu(hMenu, 1); 673 hViewMenu = GetSubMenu(hMenu, 2); 674 hShutMenu = GetSubMenu(hMenu, 4); 675 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1); 676 hCPUHistoryMenu = GetSubMenu(hViewMenu, 7); 677 678 /* Check or uncheck the always on top menu item */ 679 if (TaskManagerSettings.AlwaysOnTop) { 680 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED); 681 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); 682 } else { 683 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED); 684 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); 685 } 686 687 /* Check or uncheck the minimize on use menu item */ 688 if (TaskManagerSettings.MinimizeOnUse) 689 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_CHECKED); 690 else 691 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_UNCHECKED); 692 693 /* Check or uncheck the hide when minimized menu item */ 694 if (TaskManagerSettings.HideWhenMinimized) 695 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_CHECKED); 696 else 697 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_UNCHECKED); 698 699 /* Check or uncheck the show 16-bit tasks menu item */ 700 if (TaskManagerSettings.Show16BitTasks) 701 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED); 702 else 703 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_UNCHECKED); 704 705 /* Set the view mode */ 706 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND); 707 708 if (TaskManagerSettings.ShowKernelTimes) 709 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED); 710 else 711 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED); 712 713 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, TaskManagerSettings.UpdateSpeed, MF_BYCOMMAND); 714 715 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) 716 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); 717 else 718 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); 719 720 nActivePage = TaskManagerSettings.ActiveTabPage; 721 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 0); 722 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 1); 723 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 2); 724 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, nActivePage); 725 726 /* Set the username in the "Log Off %s" item of the Shutdown menu */ 727 728 /* 1- Get the menu item text and store it temporarily */ 729 GetMenuStringW(hShutMenu, ID_SHUTDOWN_LOGOFF, szTemp, 256, MF_BYCOMMAND); 730 731 /* 2- Retrieve the username length first, then allocate a buffer for it and call it again */ 732 if (!GetUserNameW(NULL, &len) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 733 { 734 lpUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR)); 735 if (lpUserName && GetUserNameW(lpUserName, &len)) 736 { 737 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, lpUserName); 738 szLogOffItem[sizeof(szLogOffItem)/sizeof(szLogOffItem[0]) - 1] = UNICODE_NULL; 739 } 740 else 741 { 742 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, L"n/a"); 743 } 744 745 if (lpUserName) HeapFree(GetProcessHeap(), 0, lpUserName); 746 } 747 else 748 { 749 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, L"n/a"); 750 } 751 752 /* 3- Set the menu item text to its formatted counterpart */ 753 ModifyMenuW(hShutMenu, ID_SHUTDOWN_LOGOFF, MF_BYCOMMAND | MF_STRING, ID_SHUTDOWN_LOGOFF, szLogOffItem); 754 755 /* Setup update speed */ 756 SetUpdateSpeed(hWnd); 757 758 /* 759 * Refresh the performance data 760 * Sample it twice so we can establish 761 * the delta values & cpu usage 762 */ 763 PerfDataRefresh(); 764 PerfDataRefresh(); 765 766 RefreshApplicationPage(); 767 RefreshProcessPage(); 768 RefreshPerformancePage(); 769 770 TrayIcon_ShellAddTrayIcon(); 771 772 return TRUE; 773 } 774 775 /* OnMove() 776 * This function handles all the moving events for the application 777 * It moves every child window that needs moving 778 */ 779 void OnMove( WPARAM nType, int cx, int cy ) 780 { 781 #ifdef __GNUC__TEST__ 782 MoveWindow(hApplicationPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE); 783 MoveWindow(hProcessPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE); 784 MoveWindow(hPerformancePage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE); 785 #endif 786 } 787 788 /* OnSize() 789 * This function handles all the sizing events for the application 790 * It re-sizes every window, and child window that needs re-sizing 791 */ 792 void OnSize( WPARAM nType, int cx, int cy ) 793 { 794 int nParts[3]; 795 int nXDifference; 796 int nYDifference; 797 RECT rc; 798 799 if (nType == SIZE_MINIMIZED) 800 { 801 if(TaskManagerSettings.HideWhenMinimized) 802 { 803 ShowWindow(hMainWnd, SW_HIDE); 804 } 805 return; 806 } 807 808 nXDifference = cx - nOldWidth; 809 nYDifference = cy - nOldHeight; 810 nOldWidth = cx; 811 nOldHeight = cy; 812 813 /* Update the status bar size */ 814 GetWindowRect(hStatusWnd, &rc); 815 SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx,rc.bottom - rc.top)); 816 817 /* Update the status bar pane sizes */ 818 nParts[0] = bInMenuLoop ? -1 : STATUS_SIZE1; 819 nParts[1] = STATUS_SIZE2; 820 nParts[2] = cx; 821 SendMessageW(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (LPARAM) (LPINT) nParts); 822 823 /* Resize the tab control */ 824 GetWindowRect(hTabWnd, &rc); 825 cx = (rc.right - rc.left) + nXDifference; 826 cy = (rc.bottom - rc.top) + nYDifference; 827 SetWindowPos(hTabWnd, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 828 829 /* Resize the application page */ 830 GetWindowRect(hApplicationPage, &rc); 831 cx = (rc.right - rc.left) + nXDifference; 832 cy = (rc.bottom - rc.top) + nYDifference; 833 SetWindowPos(hApplicationPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 834 835 /* Resize the process page */ 836 GetWindowRect(hProcessPage, &rc); 837 cx = (rc.right - rc.left) + nXDifference; 838 cy = (rc.bottom - rc.top) + nYDifference; 839 SetWindowPos(hProcessPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 840 841 /* Resize the performance page */ 842 GetWindowRect(hPerformancePage, &rc); 843 cx = (rc.right - rc.left) + nXDifference; 844 cy = (rc.bottom - rc.top) + nYDifference; 845 SetWindowPos(hPerformancePage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 846 } 847 848 void LoadSettings(void) 849 { 850 HKEY hKey; 851 WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager"; 852 int i; 853 DWORD dwSize; 854 855 /* Window size & position settings */ 856 TaskManagerSettings.Maximized = FALSE; 857 TaskManagerSettings.Left = 0; 858 TaskManagerSettings.Top = 0; 859 TaskManagerSettings.Right = 0; 860 TaskManagerSettings.Bottom = 0; 861 862 /* Tab settings */ 863 TaskManagerSettings.ActiveTabPage = 0; 864 865 /* Options menu settings */ 866 TaskManagerSettings.AlwaysOnTop = FALSE; 867 TaskManagerSettings.MinimizeOnUse = TRUE; 868 TaskManagerSettings.HideWhenMinimized = TRUE; 869 TaskManagerSettings.Show16BitTasks = TRUE; 870 871 /* Update speed settings */ 872 TaskManagerSettings.UpdateSpeed = ID_VIEW_UPDATESPEED_NORMAL; 873 874 /* Applications page settings */ 875 TaskManagerSettings.ViewMode = ID_VIEW_DETAILS; 876 877 /* Processes page settings */ 878 TaskManagerSettings.ShowProcessesFromAllUsers = FALSE; /* Server-only? */ 879 880 for (i = 0; i < COLUMN_NMAX; i++) { 881 TaskManagerSettings.Columns[i] = ColumnPresets[i].bDefaults; 882 TaskManagerSettings.ColumnOrderArray[i] = i; 883 TaskManagerSettings.ColumnSizeArray[i] = ColumnPresets[i].size; 884 } 885 886 TaskManagerSettings.SortColumn = COLUMN_IMAGENAME; 887 TaskManagerSettings.SortAscending = TRUE; 888 889 /* Performance page settings */ 890 TaskManagerSettings.CPUHistory_OneGraphPerCPU = TRUE; 891 TaskManagerSettings.ShowKernelTimes = FALSE; 892 893 /* Open the key */ 894 if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 895 return; 896 /* Read the settings */ 897 dwSize = sizeof(TASKMANAGER_SETTINGS); 898 RegQueryValueExW(hKey, L"Preferences", NULL, NULL, (LPBYTE)&TaskManagerSettings, &dwSize); 899 900 /* 901 * ATM, the 'ImageName' column is always visible 902 * (and grayed in configuration dialog) 903 * This will avoid troubles if the registry gets corrupted. 904 */ 905 TaskManagerSettings.Column_ImageName = TRUE; 906 907 /* Close the key */ 908 RegCloseKey(hKey); 909 } 910 911 void SaveSettings(void) 912 { 913 HKEY hKey; 914 WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager"; 915 916 /* Open (or create) the key */ 917 if (RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) 918 return; 919 /* Save the settings */ 920 RegSetValueExW(hKey, L"Preferences", 0, REG_BINARY, (LPBYTE)&TaskManagerSettings, sizeof(TASKMANAGER_SETTINGS)); 921 /* Close the key */ 922 RegCloseKey(hKey); 923 } 924 925 void TaskManager_OnRestoreMainWindow(void) 926 { 927 //HMENU hMenu, hOptionsMenu; 928 BOOL OnTop; 929 930 //hMenu = GetMenu(hMainWnd); 931 //hOptionsMenu = GetSubMenu(hMenu, OPTIONS_MENU_INDEX); 932 OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0); 933 934 OpenIcon(hMainWnd); 935 SetForegroundWindow(hMainWnd); 936 SetWindowPos(hMainWnd, (OnTop ? HWND_TOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); 937 } 938 939 void TaskManager_OnEnterMenuLoop(HWND hWnd) 940 { 941 int nParts; 942 943 /* Update the status bar pane sizes */ 944 nParts = -1; 945 SendMessageW(hStatusWnd, SB_SETPARTS, 1, (LPARAM) (LPINT)&nParts); 946 bInMenuLoop = TRUE; 947 SendMessageW(hStatusWnd, SB_SETTEXT, (WPARAM)0, (LPARAM)L""); 948 } 949 950 void TaskManager_OnExitMenuLoop(HWND hWnd) 951 { 952 RECT rc; 953 int nParts[3]; 954 955 bInMenuLoop = FALSE; 956 957 /* Update the status bar pane sizes */ 958 GetClientRect(hWnd, &rc); 959 nParts[0] = STATUS_SIZE1; 960 nParts[1] = STATUS_SIZE2; 961 nParts[2] = rc.right; 962 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts); 963 964 /* trigger update of status bar columns and performance page asynchronously */ 965 RefreshPerformancePage(); 966 } 967 968 void TaskManager_OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu) 969 { 970 WCHAR str[100]; 971 972 wcscpy(str, L""); 973 if (LoadStringW(hInst, nItemID, str, 100)) { 974 /* load appropriate string */ 975 LPWSTR lpsz = str; 976 /* first newline terminates actual string */ 977 lpsz = wcschr(lpsz, '\n'); 978 if (lpsz != NULL) 979 *lpsz = '\0'; 980 } 981 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)str); 982 } 983 984 void TaskManager_OnViewUpdateSpeed(DWORD dwSpeed) 985 { 986 HMENU hMenu; 987 HMENU hViewMenu; 988 HMENU hUpdateSpeedMenu; 989 990 hMenu = GetMenu(hMainWnd); 991 hViewMenu = GetSubMenu(hMenu, 2); 992 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1); 993 994 TaskManagerSettings.UpdateSpeed = dwSpeed; 995 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, dwSpeed, MF_BYCOMMAND); 996 997 KillTimer(hMainWnd, 1); 998 999 SetUpdateSpeed(hMainWnd); 1000 } 1001 1002 void TaskManager_OnTabWndSelChange(void) 1003 { 1004 int i; 1005 HMENU hMenu; 1006 HMENU hOptionsMenu; 1007 HMENU hViewMenu; 1008 HMENU hSubMenu; 1009 WCHAR szTemp[256]; 1010 SYSTEM_INFO sysInfo; 1011 1012 hMenu = GetMenu(hMainWnd); 1013 hViewMenu = GetSubMenu(hMenu, 2); 1014 hOptionsMenu = GetSubMenu(hMenu, 1); 1015 TaskManagerSettings.ActiveTabPage = TabCtrl_GetCurSel(hTabWnd); 1016 for (i = GetMenuItemCount(hViewMenu) - 1; i > 2; i--) { 1017 hSubMenu = GetSubMenu(hViewMenu, i); 1018 if (hSubMenu) 1019 DestroyMenu(hSubMenu); 1020 RemoveMenu(hViewMenu, i, MF_BYPOSITION); 1021 } 1022 RemoveMenu(hOptionsMenu, 3, MF_BYPOSITION); 1023 if (hWindowMenu) 1024 DestroyMenu(hWindowMenu); 1025 switch (TaskManagerSettings.ActiveTabPage) { 1026 case 0: 1027 ShowWindow(hApplicationPage, SW_SHOW); 1028 ShowWindow(hProcessPage, SW_HIDE); 1029 ShowWindow(hPerformancePage, SW_HIDE); 1030 BringWindowToTop(hApplicationPage); 1031 1032 LoadStringW(hInst, IDS_MENU_LARGEICONS, szTemp, 256); 1033 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_LARGE, szTemp); 1034 1035 LoadStringW(hInst, IDS_MENU_SMALLICONS, szTemp, 256); 1036 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SMALL, szTemp); 1037 1038 LoadStringW(hInst, IDS_MENU_DETAILS, szTemp, 256); 1039 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_DETAILS, szTemp); 1040 1041 if (GetMenuItemCount(hMenu) <= 5) { 1042 hWindowMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_WINDOWSMENU)); 1043 1044 LoadStringW(hInst, IDS_MENU_WINDOWS, szTemp, 256); 1045 InsertMenuW(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT_PTR) hWindowMenu, szTemp); 1046 1047 DrawMenuBar(hMainWnd); 1048 } 1049 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND); 1050 1051 /* 1052 * Give the application list control focus 1053 */ 1054 if (!bWasKeyboardInput) 1055 SetFocus(hApplicationPageListCtrl); 1056 break; 1057 1058 case 1: 1059 ShowWindow(hApplicationPage, SW_HIDE); 1060 ShowWindow(hProcessPage, SW_SHOW); 1061 ShowWindow(hPerformancePage, SW_HIDE); 1062 BringWindowToTop(hProcessPage); 1063 1064 LoadStringW(hInst, IDS_MENU_SELECTCOLUMNS, szTemp, 256); 1065 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, szTemp); 1066 1067 LoadStringW(hInst, IDS_MENU_16BITTASK, szTemp, 256); 1068 AppendMenuW(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, szTemp); 1069 1070 if (TaskManagerSettings.Show16BitTasks) 1071 CheckMenuItem(hOptionsMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED); 1072 if (GetMenuItemCount(hMenu) > 5) 1073 { 1074 DeleteMenu(hMenu, 3, MF_BYPOSITION); 1075 DrawMenuBar(hMainWnd); 1076 } 1077 /* 1078 * Give the process list control focus 1079 */ 1080 if (!bWasKeyboardInput) 1081 SetFocus(hProcessPageListCtrl); 1082 break; 1083 1084 case 2: 1085 ShowWindow(hApplicationPage, SW_HIDE); 1086 ShowWindow(hProcessPage, SW_HIDE); 1087 ShowWindow(hPerformancePage, SW_SHOW); 1088 BringWindowToTop(hPerformancePage); 1089 if (GetMenuItemCount(hMenu) > 5) { 1090 DeleteMenu(hMenu, 3, MF_BYPOSITION); 1091 DrawMenuBar(hMainWnd); 1092 } 1093 1094 GetSystemInfo(&sysInfo); 1095 1096 /* Hide CPU graph options on single CPU systems */ 1097 if (sysInfo.dwNumberOfProcessors > 1) 1098 { 1099 hSubMenu = CreatePopupMenu(); 1100 1101 LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256); 1102 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp); 1103 1104 LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256); 1105 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp); 1106 1107 LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256); 1108 AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp); 1109 1110 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) 1111 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); 1112 else 1113 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); 1114 } 1115 1116 LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256); 1117 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp); 1118 1119 if (TaskManagerSettings.ShowKernelTimes) 1120 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED); 1121 else 1122 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED); 1123 1124 /* 1125 * Give the tab control focus 1126 */ 1127 if (!bWasKeyboardInput) 1128 SetFocus(hTabWnd); 1129 break; 1130 } 1131 } 1132 1133 VOID ShowWin32Error(DWORD dwError) 1134 { 1135 LPWSTR lpMessageBuffer; 1136 1137 if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 1138 NULL, 1139 dwError, 1140 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 1141 (LPWSTR)&lpMessageBuffer, 1142 0, NULL) != 0) 1143 { 1144 MessageBoxW(hMainWnd, lpMessageBuffer, NULL, MB_OK | MB_ICONERROR); 1145 if (lpMessageBuffer) LocalFree(lpMessageBuffer); 1146 } 1147 } 1148 1149 LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize) 1150 { 1151 DWORD dwRet; 1152 LPWSTR lpszTemp = NULL; 1153 1154 dwRet = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, 1155 NULL, 1156 GetLastError(), 1157 LANG_NEUTRAL, 1158 (LPWSTR)&lpszTemp, 1159 0, 1160 NULL ); 1161 1162 /* supplied buffer is not long enough */ 1163 if (!dwRet || ( (long)dwSize < (long)dwRet+14)) { 1164 lpszBuf[0] = L'\0'; 1165 } else { 1166 lpszTemp[lstrlenW(lpszTemp)-2] = L'\0'; /*remove cr and newline character */ 1167 wsprintfW(lpszBuf, L"%s (0x%x)", lpszTemp, (int)GetLastError()); 1168 } 1169 if (lpszTemp) { 1170 LocalFree((HLOCAL)lpszTemp); 1171 } 1172 return lpszBuf; 1173 } 1174 1175 DWORD EndLocalThread(HANDLE *hThread, DWORD dwThread) 1176 { 1177 DWORD dwExitCodeThread = 0; 1178 1179 if (*hThread != NULL) { 1180 PostThreadMessage(dwThread,WM_QUIT,0,0); 1181 for (;;) { 1182 MSG msg; 1183 1184 if (WAIT_OBJECT_0 == WaitForSingleObject(*hThread, 500)) 1185 break; 1186 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { 1187 TranslateMessage(&msg); 1188 DispatchMessage(&msg); 1189 } 1190 } 1191 GetExitCodeThread(*hThread, &dwExitCodeThread); 1192 CloseHandle(*hThread); 1193 *hThread = NULL; 1194 } 1195 return dwExitCodeThread; 1196 } 1197 1198