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