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 //
EnableDialogTheme(HWND hwnd)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
wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nCmdShow)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
TaskManagerWndProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)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
FillSolidRect(HDC hDC,LPCRECT lpRect,COLORREF clr)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
SetUpdateSpeed(HWND hWnd)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
OnCreate(HWND hWnd)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 */
OnMove(WPARAM nType,int cx,int cy)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 */
OnSize(WPARAM nType,int cx,int cy)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
LoadSettings(void)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
SaveSettings(void)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
TaskManager_OnRestoreMainWindow(void)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
TaskManager_OnMenuSelect(HWND hWnd,UINT nItemID,UINT nFlags,HMENU hSysMenu)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
TaskManager_OnViewUpdateSpeed(DWORD dwSpeed)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
TaskManager_OnTabWndSelChange(void)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
ConfirmMessageBox(HWND hWnd,LPCWSTR Text,LPCWSTR Title,UINT Type)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
ShowWin32Error(DWORD dwError)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
GetLastErrorText(LPWSTR lpszBuf,DWORD dwSize)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
EndLocalThread(HANDLE * hThread,DWORD dwThread)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