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