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 case ID_PROCESS_PAGE_DEBUGCHANNELS: 328 ProcessPage_OnDebugChannels(); 329 break; 330 331 /* ShutDown items */ 332 case ID_SHUTDOWN_STANDBY: 333 ShutDown_StandBy(); 334 break; 335 case ID_SHUTDOWN_HIBERNATE: 336 ShutDown_Hibernate(); 337 break; 338 case ID_SHUTDOWN_POWEROFF: 339 ShutDown_PowerOff(); 340 break; 341 case ID_SHUTDOWN_REBOOT: 342 ShutDown_Reboot(); 343 break; 344 case ID_SHUTDOWN_LOGOFF: 345 ShutDown_LogOffUser(); 346 break; 347 case ID_SHUTDOWN_SWITCHUSER: 348 ShutDown_SwitchUser(); 349 break; 350 case ID_SHUTDOWN_LOCKCOMPUTER: 351 ShutDown_LockComputer(); 352 break; 353 case ID_SHUTDOWN_DISCONNECT: 354 ShutDown_Disconnect(); 355 break; 356 case ID_SHUTDOWN_EJECT_COMPUTER: 357 ShutDown_EjectComputer(); 358 break; 359 360 case ID_HELP_ABOUT: 361 OnAbout(); 362 break; 363 case ID_FILE_EXIT: 364 EndDialog(hDlg, IDOK); 365 break; 366 } 367 break; 368 369 case WM_ONTRAYICON: 370 switch(lParam) 371 { 372 case WM_RBUTTONDOWN: 373 { 374 POINT pt; 375 BOOL OnTop; 376 HMENU hMenu, hPopupMenu; 377 378 GetCursorPos(&pt); 379 380 OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0); 381 382 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_TRAY_POPUP)); 383 hPopupMenu = GetSubMenu(hMenu, 0); 384 385 if(IsWindowVisible(hMainWnd)) 386 { 387 DeleteMenu(hPopupMenu, ID_RESTORE, MF_BYCOMMAND); 388 } 389 else 390 { 391 SetMenuDefaultItem(hPopupMenu, ID_RESTORE, FALSE); 392 } 393 394 if(OnTop) 395 { 396 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_CHECKED); 397 } else 398 { 399 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_UNCHECKED); 400 } 401 402 SetForegroundWindow(hMainWnd); 403 TrackPopupMenuEx(hPopupMenu, 0, pt.x, pt.y, hMainWnd, NULL); 404 405 DestroyMenu(hMenu); 406 break; 407 } 408 case WM_LBUTTONDBLCLK: 409 TaskManager_OnRestoreMainWindow(); 410 break; 411 } 412 break; 413 414 case WM_NOTIFY: 415 pnmh = (LPNMHDR)lParam; 416 if ((pnmh->hwndFrom == hTabWnd) && 417 (pnmh->idFrom == IDC_TAB)) 418 { 419 switch (pnmh->code) 420 { 421 case TCN_SELCHANGE: 422 TaskManager_OnTabWndSelChange(); 423 break; 424 case TCN_KEYDOWN: 425 bWasKeyboardInput = TRUE; 426 break; 427 case NM_CLICK: 428 bWasKeyboardInput = FALSE; 429 break; 430 } 431 } 432 break; 433 #if 0 434 case WM_NCPAINT: 435 hdc = GetDC(hDlg); 436 GetClientRect(hDlg, &rc); 437 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT)); 438 ReleaseDC(hDlg, hdc); 439 break; 440 441 case WM_PAINT: 442 hdc = BeginPaint(hDlg, &ps); 443 GetClientRect(hDlg, &rc); 444 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT)); 445 EndPaint(hDlg, &ps); 446 break; 447 #endif 448 case WM_SIZING: 449 /* Make sure the user is sizing the dialog */ 450 /* in an acceptable range */ 451 pRC = (LPRECT)lParam; 452 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) { 453 /* If the width is too small enlarge it to the minimum */ 454 if (nMinimumWidth > (pRC->right - pRC->left)) 455 pRC->left = pRC->right - nMinimumWidth; 456 } else { 457 /* If the width is too small enlarge it to the minimum */ 458 if (nMinimumWidth > (pRC->right - pRC->left)) 459 pRC->right = pRC->left + nMinimumWidth; 460 } 461 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) { 462 /* If the height is too small enlarge it to the minimum */ 463 if (nMinimumHeight > (pRC->bottom - pRC->top)) 464 pRC->top = pRC->bottom - nMinimumHeight; 465 } else { 466 /* If the height is too small enlarge it to the minimum */ 467 if (nMinimumHeight > (pRC->bottom - pRC->top)) 468 pRC->bottom = pRC->top + nMinimumHeight; 469 } 470 return TRUE; 471 break; 472 473 case WM_SIZE: 474 /* Handle the window sizing in it's own function */ 475 OnSize(wParam, LOWORD(lParam), HIWORD(lParam)); 476 break; 477 478 case WM_MOVE: 479 /* Handle the window moving in it's own function */ 480 OnMove(wParam, LOWORD(lParam), HIWORD(lParam)); 481 break; 482 483 case WM_DESTROY: 484 ShowWindow(hDlg, SW_HIDE); 485 TrayIcon_ShellRemoveTrayIcon(); 486 wp.length = sizeof(WINDOWPLACEMENT); 487 GetWindowPlacement(hDlg, &wp); 488 TaskManagerSettings.Left = wp.rcNormalPosition.left; 489 TaskManagerSettings.Top = wp.rcNormalPosition.top; 490 TaskManagerSettings.Right = wp.rcNormalPosition.right; 491 TaskManagerSettings.Bottom = wp.rcNormalPosition.bottom; 492 if (IsZoomed(hDlg) || (wp.flags & WPF_RESTORETOMAXIMIZED)) 493 TaskManagerSettings.Maximized = TRUE; 494 else 495 TaskManagerSettings.Maximized = FALSE; 496 /* Get rid of the allocated command line cache, if any */ 497 PerfDataDeallocCommandLineCache(); 498 if (hWindowMenu) 499 DestroyMenu(hWindowMenu); 500 return DefWindowProcW(hDlg, message, wParam, lParam); 501 502 case WM_TIMER: 503 /* Refresh the performance data */ 504 PerfDataRefresh(); 505 RefreshApplicationPage(); 506 RefreshProcessPage(); 507 RefreshPerformancePage(); 508 TrayIcon_ShellUpdateTrayIcon(); 509 break; 510 511 case WM_ENTERMENULOOP: 512 TaskManager_OnEnterMenuLoop(hDlg); 513 break; 514 case WM_EXITMENULOOP: 515 TaskManager_OnExitMenuLoop(hDlg); 516 break; 517 case WM_MENUSELECT: 518 TaskManager_OnMenuSelect(hDlg, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam); 519 break; 520 case WM_SYSCOLORCHANGE: 521 /* Forward WM_SYSCOLORCHANGE to common controls */ 522 SendMessage(hApplicationPageListCtrl, WM_SYSCOLORCHANGE, 0, 0); 523 SendMessage(hProcessPageListCtrl, WM_SYSCOLORCHANGE, 0, 0); 524 SendMessage(hProcessPageHeaderCtrl, WM_SYSCOLORCHANGE, 0, 0); 525 break; 526 } 527 528 return 0; 529 } 530 531 void FillSolidRect(HDC hDC, LPCRECT lpRect, COLORREF clr) 532 { 533 SetBkColor(hDC, clr); 534 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); 535 } 536 537 void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr) 538 { 539 RECT rect; 540 541 SetBkColor(hDC, clr); 542 rect.left = x; 543 rect.top = y; 544 rect.right = x + cx; 545 rect.bottom = y + cy; 546 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); 547 } 548 549 void Draw3dRect(HDC hDC, int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight) 550 { 551 FillSolidRect2(hDC, x, y, cx - 1, 1, clrTopLeft); 552 FillSolidRect2(hDC, x, y, 1, cy - 1, clrTopLeft); 553 FillSolidRect2(hDC, x + cx, y, -1, cy, clrBottomRight); 554 FillSolidRect2(hDC, x, y + cy, cx, -1, clrBottomRight); 555 } 556 557 void Draw3dRect2(HDC hDC, LPRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight) 558 { 559 Draw3dRect(hDC, lpRect->left, lpRect->top, lpRect->right - lpRect->left, 560 lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight); 561 } 562 563 static void SetUpdateSpeed(HWND hWnd) 564 { 565 /* Setup update speed (pause=fall down) */ 566 switch (TaskManagerSettings.UpdateSpeed) { 567 case ID_VIEW_UPDATESPEED_HIGH: 568 SetTimer(hWnd, 1, 1000, NULL); 569 break; 570 case ID_VIEW_UPDATESPEED_NORMAL: 571 SetTimer(hWnd, 1, 2000, NULL); 572 break; 573 case ID_VIEW_UPDATESPEED_LOW: 574 SetTimer(hWnd, 1, 4000, NULL); 575 break; 576 } 577 } 578 579 BOOL OnCreate(HWND hWnd) 580 { 581 HMENU hMenu; 582 HMENU hEditMenu; 583 HMENU hViewMenu; 584 HMENU hShutMenu; 585 HMENU hUpdateSpeedMenu; 586 HMENU hCPUHistoryMenu; 587 int nActivePage; 588 int nParts[3]; 589 RECT rc; 590 WCHAR szTemp[256]; 591 WCHAR szLogOffItem[MAX_PATH]; 592 LPWSTR lpUserName; 593 TCITEM item; 594 DWORD len = 0; 595 596 SendMessageW(hMainWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_TASKMANAGER))); 597 598 /* Initialize the Windows Common Controls DLL */ 599 InitCommonControls(); 600 601 /* Get the minimum window sizes */ 602 GetWindowRect(hWnd, &rc); 603 nMinimumWidth = (rc.right - rc.left); 604 nMinimumHeight = (rc.bottom - rc.top); 605 606 /* Create the status bar */ 607 hStatusWnd = CreateStatusWindow(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS, L"", hWnd, STATUS_WINDOW); 608 if(!hStatusWnd) 609 return FALSE; 610 611 /* Create the status bar panes */ 612 nParts[0] = STATUS_SIZE1; 613 nParts[1] = STATUS_SIZE2; 614 nParts[2] = STATUS_SIZE3; 615 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts); 616 617 /* Create tab pages */ 618 hTabWnd = GetDlgItem(hWnd, IDC_TAB); 619 #if 1 620 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hWnd, ApplicationPageWndProc); EnableDialogTheme(hApplicationPage); 621 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hWnd, ProcessPageWndProc); EnableDialogTheme(hProcessPage); 622 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hWnd, PerformancePageWndProc); EnableDialogTheme(hPerformancePage); 623 #else 624 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hTabWnd, ApplicationPageWndProc); EnableDialogTheme(hApplicationPage); 625 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hTabWnd, ProcessPageWndProc); EnableDialogTheme(hProcessPage); 626 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hTabWnd, PerformancePageWndProc); EnableDialogTheme(hPerformancePage); 627 #endif 628 629 /* Insert tabs */ 630 LoadStringW(hInst, IDS_TAB_APPS, szTemp, 256); 631 memset(&item, 0, sizeof(TCITEM)); 632 item.mask = TCIF_TEXT; 633 item.pszText = szTemp; 634 (void)TabCtrl_InsertItem(hTabWnd, 0, &item); 635 LoadStringW(hInst, IDS_TAB_PROCESSES, szTemp, 256); 636 memset(&item, 0, sizeof(TCITEM)); 637 item.mask = TCIF_TEXT; 638 item.pszText = szTemp; 639 (void)TabCtrl_InsertItem(hTabWnd, 1, &item); 640 LoadStringW(hInst, IDS_TAB_PERFORMANCE, szTemp, 256); 641 memset(&item, 0, sizeof(TCITEM)); 642 item.mask = TCIF_TEXT; 643 item.pszText = szTemp; 644 (void)TabCtrl_InsertItem(hTabWnd, 2, &item); 645 646 /* Size everything correctly */ 647 GetClientRect(hWnd, &rc); 648 nOldWidth = rc.right; 649 nOldHeight = rc.bottom; 650 /* nOldStartX = rc.left; */ 651 /*nOldStartY = rc.top; */ 652 653 #define PAGE_OFFSET_LEFT 17 654 #define PAGE_OFFSET_TOP 72 655 #define PAGE_OFFSET_WIDTH (PAGE_OFFSET_LEFT*2) 656 #define PAGE_OFFSET_HEIGHT (PAGE_OFFSET_TOP+32) 657 658 if ((TaskManagerSettings.Left != 0) || 659 (TaskManagerSettings.Top != 0) || 660 (TaskManagerSettings.Right != 0) || 661 (TaskManagerSettings.Bottom != 0)) 662 { 663 MoveWindow(hWnd, TaskManagerSettings.Left, TaskManagerSettings.Top, TaskManagerSettings.Right - TaskManagerSettings.Left, TaskManagerSettings.Bottom - TaskManagerSettings.Top, TRUE); 664 #ifdef __GNUC__TEST__ 665 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); 666 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); 667 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); 668 #endif 669 } 670 if (TaskManagerSettings.Maximized) 671 ShowWindow(hWnd, SW_MAXIMIZE); 672 673 /* Set the always on top style */ 674 hMenu = GetMenu(hWnd); 675 hEditMenu = GetSubMenu(hMenu, 1); 676 hViewMenu = GetSubMenu(hMenu, 2); 677 hShutMenu = GetSubMenu(hMenu, 4); 678 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1); 679 hCPUHistoryMenu = GetSubMenu(hViewMenu, 7); 680 681 /* Check or uncheck the always on top menu item */ 682 if (TaskManagerSettings.AlwaysOnTop) { 683 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED); 684 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); 685 } else { 686 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED); 687 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); 688 } 689 690 /* Check or uncheck the minimize on use menu item */ 691 if (TaskManagerSettings.MinimizeOnUse) 692 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_CHECKED); 693 else 694 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_UNCHECKED); 695 696 /* Check or uncheck the hide when minimized menu item */ 697 if (TaskManagerSettings.HideWhenMinimized) 698 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_CHECKED); 699 else 700 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_UNCHECKED); 701 702 /* Check or uncheck the show 16-bit tasks menu item */ 703 if (TaskManagerSettings.Show16BitTasks) 704 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED); 705 else 706 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_UNCHECKED); 707 708 /* Set the view mode */ 709 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND); 710 711 if (TaskManagerSettings.ShowKernelTimes) 712 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED); 713 else 714 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED); 715 716 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, TaskManagerSettings.UpdateSpeed, MF_BYCOMMAND); 717 718 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) 719 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); 720 else 721 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); 722 723 nActivePage = TaskManagerSettings.ActiveTabPage; 724 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 0); 725 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 1); 726 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 2); 727 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, nActivePage); 728 729 /* Set the username in the "Log Off %s" item of the Shutdown menu */ 730 731 /* 1- Get the menu item text and store it temporarily */ 732 GetMenuStringW(hShutMenu, ID_SHUTDOWN_LOGOFF, szTemp, 256, MF_BYCOMMAND); 733 734 /* 2- Retrieve the username length first, then allocate a buffer for it and call it again */ 735 if (!GetUserNameW(NULL, &len) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 736 { 737 lpUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR)); 738 if (lpUserName && GetUserNameW(lpUserName, &len)) 739 { 740 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, lpUserName); 741 szLogOffItem[sizeof(szLogOffItem)/sizeof(szLogOffItem[0]) - 1] = UNICODE_NULL; 742 } 743 else 744 { 745 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, L"n/a"); 746 } 747 748 if (lpUserName) HeapFree(GetProcessHeap(), 0, lpUserName); 749 } 750 else 751 { 752 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, L"n/a"); 753 } 754 755 /* 3- Set the menu item text to its formatted counterpart */ 756 ModifyMenuW(hShutMenu, ID_SHUTDOWN_LOGOFF, MF_BYCOMMAND | MF_STRING, ID_SHUTDOWN_LOGOFF, szLogOffItem); 757 758 /* Setup update speed */ 759 SetUpdateSpeed(hWnd); 760 761 /* 762 * Refresh the performance data 763 * Sample it twice so we can establish 764 * the delta values & cpu usage 765 */ 766 PerfDataRefresh(); 767 PerfDataRefresh(); 768 769 RefreshApplicationPage(); 770 RefreshProcessPage(); 771 RefreshPerformancePage(); 772 773 TrayIcon_ShellAddTrayIcon(); 774 775 return TRUE; 776 } 777 778 /* OnMove() 779 * This function handles all the moving events for the application 780 * It moves every child window that needs moving 781 */ 782 void OnMove( WPARAM nType, int cx, int cy ) 783 { 784 #ifdef __GNUC__TEST__ 785 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); 786 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); 787 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); 788 #endif 789 } 790 791 /* OnSize() 792 * This function handles all the sizing events for the application 793 * It re-sizes every window, and child window that needs re-sizing 794 */ 795 void OnSize( WPARAM nType, int cx, int cy ) 796 { 797 int nParts[3]; 798 int nXDifference; 799 int nYDifference; 800 RECT rc; 801 802 if (nType == SIZE_MINIMIZED) 803 { 804 if(TaskManagerSettings.HideWhenMinimized) 805 { 806 ShowWindow(hMainWnd, SW_HIDE); 807 } 808 return; 809 } 810 811 nXDifference = cx - nOldWidth; 812 nYDifference = cy - nOldHeight; 813 nOldWidth = cx; 814 nOldHeight = cy; 815 816 /* Update the status bar size */ 817 GetWindowRect(hStatusWnd, &rc); 818 SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx,rc.bottom - rc.top)); 819 820 /* Update the status bar pane sizes */ 821 nParts[0] = bInMenuLoop ? -1 : STATUS_SIZE1; 822 nParts[1] = STATUS_SIZE2; 823 nParts[2] = cx; 824 SendMessageW(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (LPARAM) (LPINT) nParts); 825 826 /* Resize the tab control */ 827 GetWindowRect(hTabWnd, &rc); 828 cx = (rc.right - rc.left) + nXDifference; 829 cy = (rc.bottom - rc.top) + nYDifference; 830 SetWindowPos(hTabWnd, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 831 832 /* Resize the application page */ 833 GetWindowRect(hApplicationPage, &rc); 834 cx = (rc.right - rc.left) + nXDifference; 835 cy = (rc.bottom - rc.top) + nYDifference; 836 SetWindowPos(hApplicationPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 837 838 /* Resize the process page */ 839 GetWindowRect(hProcessPage, &rc); 840 cx = (rc.right - rc.left) + nXDifference; 841 cy = (rc.bottom - rc.top) + nYDifference; 842 SetWindowPos(hProcessPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 843 844 /* Resize the performance page */ 845 GetWindowRect(hPerformancePage, &rc); 846 cx = (rc.right - rc.left) + nXDifference; 847 cy = (rc.bottom - rc.top) + nYDifference; 848 SetWindowPos(hPerformancePage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); 849 } 850 851 void LoadSettings(void) 852 { 853 HKEY hKey; 854 WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager"; 855 int i; 856 DWORD dwSize; 857 858 /* Window size & position settings */ 859 TaskManagerSettings.Maximized = FALSE; 860 TaskManagerSettings.Left = 0; 861 TaskManagerSettings.Top = 0; 862 TaskManagerSettings.Right = 0; 863 TaskManagerSettings.Bottom = 0; 864 865 /* Tab settings */ 866 TaskManagerSettings.ActiveTabPage = 0; 867 868 /* Options menu settings */ 869 TaskManagerSettings.AlwaysOnTop = FALSE; 870 TaskManagerSettings.MinimizeOnUse = TRUE; 871 TaskManagerSettings.HideWhenMinimized = TRUE; 872 TaskManagerSettings.Show16BitTasks = TRUE; 873 874 /* Update speed settings */ 875 TaskManagerSettings.UpdateSpeed = ID_VIEW_UPDATESPEED_NORMAL; 876 877 /* Applications page settings */ 878 TaskManagerSettings.ViewMode = ID_VIEW_DETAILS; 879 880 /* Processes page settings */ 881 TaskManagerSettings.ShowProcessesFromAllUsers = FALSE; /* Server-only? */ 882 883 for (i = 0; i < COLUMN_NMAX; i++) { 884 TaskManagerSettings.Columns[i] = ColumnPresets[i].bDefaults; 885 TaskManagerSettings.ColumnOrderArray[i] = i; 886 TaskManagerSettings.ColumnSizeArray[i] = ColumnPresets[i].size; 887 } 888 889 TaskManagerSettings.SortColumn = COLUMN_IMAGENAME; 890 TaskManagerSettings.SortAscending = TRUE; 891 892 /* Performance page settings */ 893 TaskManagerSettings.CPUHistory_OneGraphPerCPU = TRUE; 894 TaskManagerSettings.ShowKernelTimes = FALSE; 895 896 /* Open the key */ 897 if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 898 return; 899 /* Read the settings */ 900 dwSize = sizeof(TASKMANAGER_SETTINGS); 901 RegQueryValueExW(hKey, L"Preferences", NULL, NULL, (LPBYTE)&TaskManagerSettings, &dwSize); 902 903 /* 904 * ATM, the 'ImageName' column is always visible 905 * (and grayed in configuration dialog) 906 * This will avoid troubles if the registry gets corrupted. 907 */ 908 TaskManagerSettings.Column_ImageName = TRUE; 909 910 /* Close the key */ 911 RegCloseKey(hKey); 912 } 913 914 void SaveSettings(void) 915 { 916 HKEY hKey; 917 WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager"; 918 919 /* Open (or create) the key */ 920 if (RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) 921 return; 922 /* Save the settings */ 923 RegSetValueExW(hKey, L"Preferences", 0, REG_BINARY, (LPBYTE)&TaskManagerSettings, sizeof(TASKMANAGER_SETTINGS)); 924 /* Close the key */ 925 RegCloseKey(hKey); 926 } 927 928 void TaskManager_OnRestoreMainWindow(void) 929 { 930 //HMENU hMenu, hOptionsMenu; 931 BOOL OnTop; 932 933 //hMenu = GetMenu(hMainWnd); 934 //hOptionsMenu = GetSubMenu(hMenu, OPTIONS_MENU_INDEX); 935 OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0); 936 937 OpenIcon(hMainWnd); 938 SetForegroundWindow(hMainWnd); 939 SetWindowPos(hMainWnd, (OnTop ? HWND_TOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); 940 } 941 942 void TaskManager_OnEnterMenuLoop(HWND hWnd) 943 { 944 int nParts; 945 946 /* Update the status bar pane sizes */ 947 nParts = -1; 948 SendMessageW(hStatusWnd, SB_SETPARTS, 1, (LPARAM) (LPINT)&nParts); 949 bInMenuLoop = TRUE; 950 SendMessageW(hStatusWnd, SB_SETTEXT, (WPARAM)0, (LPARAM)L""); 951 } 952 953 void TaskManager_OnExitMenuLoop(HWND hWnd) 954 { 955 RECT rc; 956 int nParts[3]; 957 958 bInMenuLoop = FALSE; 959 960 /* Update the status bar pane sizes */ 961 GetClientRect(hWnd, &rc); 962 nParts[0] = STATUS_SIZE1; 963 nParts[1] = STATUS_SIZE2; 964 nParts[2] = rc.right; 965 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts); 966 967 /* trigger update of status bar columns and performance page asynchronously */ 968 RefreshPerformancePage(); 969 } 970 971 void TaskManager_OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu) 972 { 973 WCHAR str[100]; 974 975 wcscpy(str, L""); 976 if (LoadStringW(hInst, nItemID, str, 100)) { 977 /* load appropriate string */ 978 LPWSTR lpsz = str; 979 /* first newline terminates actual string */ 980 lpsz = wcschr(lpsz, '\n'); 981 if (lpsz != NULL) 982 *lpsz = '\0'; 983 } 984 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)str); 985 } 986 987 void TaskManager_OnViewUpdateSpeed(DWORD dwSpeed) 988 { 989 HMENU hMenu; 990 HMENU hViewMenu; 991 HMENU hUpdateSpeedMenu; 992 993 hMenu = GetMenu(hMainWnd); 994 hViewMenu = GetSubMenu(hMenu, 2); 995 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1); 996 997 TaskManagerSettings.UpdateSpeed = dwSpeed; 998 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, dwSpeed, MF_BYCOMMAND); 999 1000 KillTimer(hMainWnd, 1); 1001 1002 SetUpdateSpeed(hMainWnd); 1003 } 1004 1005 void TaskManager_OnTabWndSelChange(void) 1006 { 1007 int i; 1008 HMENU hMenu; 1009 HMENU hOptionsMenu; 1010 HMENU hViewMenu; 1011 HMENU hSubMenu; 1012 WCHAR szTemp[256]; 1013 SYSTEM_INFO sysInfo; 1014 1015 hMenu = GetMenu(hMainWnd); 1016 hViewMenu = GetSubMenu(hMenu, 2); 1017 hOptionsMenu = GetSubMenu(hMenu, 1); 1018 TaskManagerSettings.ActiveTabPage = TabCtrl_GetCurSel(hTabWnd); 1019 for (i = GetMenuItemCount(hViewMenu) - 1; i > 2; i--) { 1020 hSubMenu = GetSubMenu(hViewMenu, i); 1021 if (hSubMenu) 1022 DestroyMenu(hSubMenu); 1023 RemoveMenu(hViewMenu, i, MF_BYPOSITION); 1024 } 1025 RemoveMenu(hOptionsMenu, 3, MF_BYPOSITION); 1026 if (hWindowMenu) 1027 DestroyMenu(hWindowMenu); 1028 switch (TaskManagerSettings.ActiveTabPage) { 1029 case 0: 1030 ShowWindow(hApplicationPage, SW_SHOW); 1031 ShowWindow(hProcessPage, SW_HIDE); 1032 ShowWindow(hPerformancePage, SW_HIDE); 1033 BringWindowToTop(hApplicationPage); 1034 1035 LoadStringW(hInst, IDS_MENU_LARGEICONS, szTemp, 256); 1036 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_LARGE, szTemp); 1037 1038 LoadStringW(hInst, IDS_MENU_SMALLICONS, szTemp, 256); 1039 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SMALL, szTemp); 1040 1041 LoadStringW(hInst, IDS_MENU_DETAILS, szTemp, 256); 1042 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_DETAILS, szTemp); 1043 1044 if (GetMenuItemCount(hMenu) <= 5) { 1045 hWindowMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_WINDOWSMENU)); 1046 1047 LoadStringW(hInst, IDS_MENU_WINDOWS, szTemp, 256); 1048 InsertMenuW(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT_PTR) hWindowMenu, szTemp); 1049 1050 DrawMenuBar(hMainWnd); 1051 } 1052 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND); 1053 1054 /* 1055 * Give the application list control focus 1056 */ 1057 if (!bWasKeyboardInput) 1058 SetFocus(hApplicationPageListCtrl); 1059 break; 1060 1061 case 1: 1062 ShowWindow(hApplicationPage, SW_HIDE); 1063 ShowWindow(hProcessPage, SW_SHOW); 1064 ShowWindow(hPerformancePage, SW_HIDE); 1065 BringWindowToTop(hProcessPage); 1066 1067 LoadStringW(hInst, IDS_MENU_SELECTCOLUMNS, szTemp, 256); 1068 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, szTemp); 1069 1070 LoadStringW(hInst, IDS_MENU_16BITTASK, szTemp, 256); 1071 AppendMenuW(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, szTemp); 1072 1073 if (TaskManagerSettings.Show16BitTasks) 1074 CheckMenuItem(hOptionsMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED); 1075 if (GetMenuItemCount(hMenu) > 5) 1076 { 1077 DeleteMenu(hMenu, 3, MF_BYPOSITION); 1078 DrawMenuBar(hMainWnd); 1079 } 1080 /* 1081 * Give the process list control focus 1082 */ 1083 if (!bWasKeyboardInput) 1084 SetFocus(hProcessPageListCtrl); 1085 break; 1086 1087 case 2: 1088 ShowWindow(hApplicationPage, SW_HIDE); 1089 ShowWindow(hProcessPage, SW_HIDE); 1090 ShowWindow(hPerformancePage, SW_SHOW); 1091 BringWindowToTop(hPerformancePage); 1092 if (GetMenuItemCount(hMenu) > 5) { 1093 DeleteMenu(hMenu, 3, MF_BYPOSITION); 1094 DrawMenuBar(hMainWnd); 1095 } 1096 1097 GetSystemInfo(&sysInfo); 1098 1099 /* Hide CPU graph options on single CPU systems */ 1100 if (sysInfo.dwNumberOfProcessors > 1) 1101 { 1102 hSubMenu = CreatePopupMenu(); 1103 1104 LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256); 1105 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp); 1106 1107 LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256); 1108 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp); 1109 1110 LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256); 1111 AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp); 1112 1113 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) 1114 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); 1115 else 1116 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); 1117 } 1118 1119 LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256); 1120 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp); 1121 1122 if (TaskManagerSettings.ShowKernelTimes) 1123 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED); 1124 else 1125 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED); 1126 1127 /* 1128 * Give the tab control focus 1129 */ 1130 if (!bWasKeyboardInput) 1131 SetFocus(hTabWnd); 1132 break; 1133 } 1134 } 1135 1136 VOID ShowWin32Error(DWORD dwError) 1137 { 1138 LPWSTR lpMessageBuffer; 1139 1140 if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 1141 NULL, 1142 dwError, 1143 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 1144 (LPWSTR)&lpMessageBuffer, 1145 0, NULL) != 0) 1146 { 1147 MessageBoxW(hMainWnd, lpMessageBuffer, NULL, MB_OK | MB_ICONERROR); 1148 if (lpMessageBuffer) LocalFree(lpMessageBuffer); 1149 } 1150 } 1151 1152 LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize) 1153 { 1154 DWORD dwRet; 1155 LPWSTR lpszTemp = NULL; 1156 1157 dwRet = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, 1158 NULL, 1159 GetLastError(), 1160 LANG_NEUTRAL, 1161 (LPWSTR)&lpszTemp, 1162 0, 1163 NULL ); 1164 1165 /* supplied buffer is not long enough */ 1166 if (!dwRet || ( (long)dwSize < (long)dwRet+14)) { 1167 lpszBuf[0] = L'\0'; 1168 } else { 1169 lpszTemp[lstrlenW(lpszTemp)-2] = L'\0'; /*remove cr and newline character */ 1170 wsprintfW(lpszBuf, L"%s (0x%x)", lpszTemp, (int)GetLastError()); 1171 } 1172 if (lpszTemp) { 1173 LocalFree((HLOCAL)lpszTemp); 1174 } 1175 return lpszBuf; 1176 } 1177 1178 DWORD EndLocalThread(HANDLE *hThread, DWORD dwThread) 1179 { 1180 DWORD dwExitCodeThread = 0; 1181 1182 if (*hThread != NULL) { 1183 PostThreadMessage(dwThread,WM_QUIT,0,0); 1184 for (;;) { 1185 MSG msg; 1186 1187 if (WAIT_OBJECT_0 == WaitForSingleObject(*hThread, 500)) 1188 break; 1189 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { 1190 TranslateMessage(&msg); 1191 DispatchMessage(&msg); 1192 } 1193 } 1194 GetExitCodeThread(*hThread, &dwExitCodeThread); 1195 CloseHandle(*hThread); 1196 *hThread = NULL; 1197 } 1198 return dwExitCodeThread; 1199 } 1200 1201