Get rid of much more duplicated code in taskmgr (patch by Carlo Bramini, carlo DOT...
[reactos.git] / reactos / base / applications / taskmgr / taskmgr.c
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include <precomp.h>
25
26 #define STATUS_WINDOW 2001
27
28 /* Global Variables: */
29 HINSTANCE hInst; /* current instance */
30
31 HWND hMainWnd; /* Main Window */
32 HWND hStatusWnd; /* Status Bar Window */
33 HWND hTabWnd; /* Tab Control Window */
34
35 int nMinimumWidth; /* Minimum width of the dialog (OnSize()'s cx) */
36 int nMinimumHeight; /* Minimum height of the dialog (OnSize()'s cy) */
37
38 int nOldWidth; /* Holds the previous client area width */
39 int nOldHeight; /* Holds the previous client area height */
40
41 BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
42
43 TASKMANAGER_SETTINGS TaskManagerSettings;
44
45
46 int APIENTRY wWinMain(HINSTANCE hInstance,
47 HINSTANCE hPrevInstance,
48 LPWSTR lpCmdLine,
49 int nCmdShow)
50 {
51 HANDLE hProcess;
52 HANDLE hToken;
53 TOKEN_PRIVILEGES tkp;
54
55 /* Initialize global variables */
56 hInst = hInstance;
57
58 /* Change our priority class to HIGH */
59 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
60 SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS);
61 CloseHandle(hProcess);
62
63 /* Now lets get the SE_DEBUG_NAME privilege
64 * so that we can debug processes
65 */
66
67 /* Get a token for this process. */
68 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
69 /* Get the LUID for the debug privilege. */
70 LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
71
72 tkp.PrivilegeCount = 1; /* one privilege to set */
73 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
74
75 /* Get the debug privilege for this process. */
76 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
77 CloseHandle(hToken);
78 }
79
80 /* Load our settings from the registry */
81 LoadSettings();
82
83 /* Initialize perf data */
84 if (!PerfDataInitialize()) {
85 return -1;
86 }
87
88 DialogBoxW(hInst, (LPCWSTR)IDD_TASKMGR_DIALOG, NULL, TaskManagerWndProc);
89
90 /* Save our settings to the registry */
91 SaveSettings();
92 PerfDataUninitialize();
93 return 0;
94 }
95
96 /* Message handler for dialog box. */
97 INT_PTR CALLBACK
98 TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
99 {
100 HDC hdc;
101 PAINTSTRUCT ps;
102 LPRECT pRC;
103 RECT rc;
104 int idctrl;
105 LPNMHDR pnmh;
106 WINDOWPLACEMENT wp;
107
108 switch (message) {
109 case WM_INITDIALOG:
110 hMainWnd = hDlg;
111 return OnCreate(hDlg);
112
113 case WM_COMMAND:
114 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
115 EndDialog(hDlg, LOWORD(wParam));
116 return TRUE;
117 }
118 /* Process menu commands */
119 switch (LOWORD(wParam))
120 {
121 case ID_FILE_NEW:
122 TaskManager_OnFileNew();
123 break;
124 case ID_OPTIONS_ALWAYSONTOP:
125 TaskManager_OnOptionsAlwaysOnTop();
126 break;
127 case ID_OPTIONS_MINIMIZEONUSE:
128 TaskManager_OnOptionsMinimizeOnUse();
129 break;
130 case ID_OPTIONS_HIDEWHENMINIMIZED:
131 TaskManager_OnOptionsHideWhenMinimized();
132 break;
133 case ID_OPTIONS_SHOW16BITTASKS:
134 TaskManager_OnOptionsShow16BitTasks();
135 break;
136 case ID_RESTORE:
137 TaskManager_OnRestoreMainWindow();
138 break;
139 case ID_VIEW_LARGE:
140 ApplicationPage_OnViewLargeIcons();
141 break;
142 case ID_VIEW_SMALL:
143 ApplicationPage_OnViewSmallIcons();
144 break;
145 case ID_VIEW_DETAILS:
146 ApplicationPage_OnViewDetails();
147 break;
148 case ID_VIEW_SHOWKERNELTIMES:
149 PerformancePage_OnViewShowKernelTimes();
150 break;
151 case ID_VIEW_CPUHISTORY_ONEGRAPHALL:
152 PerformancePage_OnViewCPUHistoryOneGraphAll();
153 break;
154 case ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU:
155 PerformancePage_OnViewCPUHistoryOneGraphPerCPU();
156 break;
157 case ID_VIEW_UPDATESPEED_HIGH:
158 TaskManager_OnViewUpdateSpeedHigh();
159 break;
160 case ID_VIEW_UPDATESPEED_NORMAL:
161 TaskManager_OnViewUpdateSpeedNormal();
162 break;
163 case ID_VIEW_UPDATESPEED_LOW:
164 TaskManager_OnViewUpdateSpeedLow();
165 break;
166 case ID_VIEW_UPDATESPEED_PAUSED:
167 TaskManager_OnViewUpdateSpeedPaused();
168 break;
169 case ID_VIEW_SELECTCOLUMNS:
170 ProcessPage_OnViewSelectColumns();
171 break;
172 case ID_VIEW_REFRESH:
173 PostMessageW(hDlg, WM_TIMER, 0, 0);
174 break;
175 case ID_WINDOWS_TILEHORIZONTALLY:
176 ApplicationPage_OnWindowsTileHorizontally();
177 break;
178 case ID_WINDOWS_TILEVERTICALLY:
179 ApplicationPage_OnWindowsTileVertically();
180 break;
181 case ID_WINDOWS_MINIMIZE:
182 ApplicationPage_OnWindowsMinimize();
183 break;
184 case ID_WINDOWS_MAXIMIZE:
185 ApplicationPage_OnWindowsMaximize();
186 break;
187 case ID_WINDOWS_CASCADE:
188 ApplicationPage_OnWindowsCascade();
189 break;
190 case ID_WINDOWS_BRINGTOFRONT:
191 ApplicationPage_OnWindowsBringToFront();
192 break;
193 case ID_APPLICATION_PAGE_SWITCHTO:
194 ApplicationPage_OnSwitchTo();
195 break;
196 case ID_APPLICATION_PAGE_ENDTASK:
197 ApplicationPage_OnEndTask();
198 break;
199 case ID_APPLICATION_PAGE_GOTOPROCESS:
200 ApplicationPage_OnGotoProcess();
201 break;
202 case ID_PROCESS_PAGE_ENDPROCESS:
203 ProcessPage_OnEndProcess();
204 break;
205 case ID_PROCESS_PAGE_ENDPROCESSTREE:
206 ProcessPage_OnEndProcessTree();
207 break;
208 case ID_PROCESS_PAGE_DEBUG:
209 ProcessPage_OnDebug();
210 break;
211 case ID_PROCESS_PAGE_SETAFFINITY:
212 ProcessPage_OnSetAffinity();
213 break;
214 case ID_PROCESS_PAGE_SETPRIORITY_REALTIME:
215 DoSetPriority(REALTIME_PRIORITY_CLASS);
216 break;
217 case ID_PROCESS_PAGE_SETPRIORITY_HIGH:
218 DoSetPriority(HIGH_PRIORITY_CLASS);
219 break;
220 case ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL:
221 DoSetPriority(ABOVE_NORMAL_PRIORITY_CLASS);
222 break;
223 case ID_PROCESS_PAGE_SETPRIORITY_NORMAL:
224 DoSetPriority(NORMAL_PRIORITY_CLASS);
225 break;
226 case ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL:
227 DoSetPriority(BELOW_NORMAL_PRIORITY_CLASS);
228 break;
229 case ID_PROCESS_PAGE_SETPRIORITY_LOW:
230 DoSetPriority(IDLE_PRIORITY_CLASS);
231 break;
232 case ID_PROCESS_PAGE_DEBUGCHANNELS:
233 ProcessPage_OnDebugChannels();
234 break;
235 case ID_HELP_ABOUT:
236 OnAbout();
237 break;
238 case ID_FILE_EXIT:
239 EndDialog(hDlg, IDOK);
240 break;
241 }
242 break;
243
244 case WM_ONTRAYICON:
245 switch(lParam)
246 {
247 case WM_RBUTTONDOWN:
248 {
249 POINT pt;
250 BOOL OnTop;
251 HMENU hMenu, hPopupMenu;
252
253 GetCursorPos(&pt);
254
255 OnTop = ((GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
256
257 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_TRAY_POPUP));
258 hPopupMenu = GetSubMenu(hMenu, 0);
259
260 if(IsWindowVisible(hMainWnd))
261 {
262 DeleteMenu(hPopupMenu, ID_RESTORE, MF_BYCOMMAND);
263 }
264 else
265 {
266 SetMenuDefaultItem(hPopupMenu, ID_RESTORE, FALSE);
267 }
268
269 if(OnTop)
270 {
271 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_CHECKED);
272 }
273
274 SetForegroundWindow(hMainWnd);
275 TrackPopupMenuEx(hPopupMenu, 0, pt.x, pt.y, hMainWnd, NULL);
276
277 DestroyMenu(hMenu);
278 break;
279 }
280 case WM_LBUTTONDBLCLK:
281 TaskManager_OnRestoreMainWindow();
282 break;
283 }
284 break;
285
286 case WM_NOTIFY:
287 idctrl = (int)wParam;
288 pnmh = (LPNMHDR)lParam;
289 if ((pnmh->hwndFrom == hTabWnd) &&
290 (pnmh->idFrom == IDC_TAB) &&
291 (pnmh->code == TCN_SELCHANGE))
292 {
293 TaskManager_OnTabWndSelChange();
294 }
295 break;
296
297 case WM_NCPAINT:
298 hdc = GetDC(hDlg);
299 GetClientRect(hDlg, &rc);
300 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
301 ReleaseDC(hDlg, hdc);
302 break;
303
304 case WM_PAINT:
305 hdc = BeginPaint(hDlg, &ps);
306 GetClientRect(hDlg, &rc);
307 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
308 EndPaint(hDlg, &ps);
309 break;
310
311 case WM_SIZING:
312 /* Make sure the user is sizing the dialog */
313 /* in an acceptable range */
314 pRC = (LPRECT)lParam;
315 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) {
316 /* If the width is too small enlarge it to the minimum */
317 if (nMinimumWidth > (pRC->right - pRC->left))
318 pRC->left = pRC->right - nMinimumWidth;
319 } else {
320 /* If the width is too small enlarge it to the minimum */
321 if (nMinimumWidth > (pRC->right - pRC->left))
322 pRC->right = pRC->left + nMinimumWidth;
323 }
324 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) {
325 /* If the height is too small enlarge it to the minimum */
326 if (nMinimumHeight > (pRC->bottom - pRC->top))
327 pRC->top = pRC->bottom - nMinimumHeight;
328 } else {
329 /* If the height is too small enlarge it to the minimum */
330 if (nMinimumHeight > (pRC->bottom - pRC->top))
331 pRC->bottom = pRC->top + nMinimumHeight;
332 }
333 return TRUE;
334 break;
335
336 case WM_SIZE:
337 /* Handle the window sizing in it's own function */
338 OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
339 break;
340
341 case WM_MOVE:
342 /* Handle the window moving in it's own function */
343 OnMove(wParam, LOWORD(lParam), HIWORD(lParam));
344 break;
345
346 case WM_DESTROY:
347 ShowWindow(hDlg, SW_HIDE);
348 TrayIcon_ShellRemoveTrayIcon();
349 wp.length = sizeof(WINDOWPLACEMENT);
350 GetWindowPlacement(hDlg, &wp);
351 TaskManagerSettings.Left = wp.rcNormalPosition.left;
352 TaskManagerSettings.Top = wp.rcNormalPosition.top;
353 TaskManagerSettings.Right = wp.rcNormalPosition.right;
354 TaskManagerSettings.Bottom = wp.rcNormalPosition.bottom;
355 if (IsZoomed(hDlg) || (wp.flags & WPF_RESTORETOMAXIMIZED))
356 TaskManagerSettings.Maximized = TRUE;
357 else
358 TaskManagerSettings.Maximized = FALSE;
359 return DefWindowProcW(hDlg, message, wParam, lParam);
360
361 case WM_TIMER:
362 /* Refresh the performance data */
363 PerfDataRefresh();
364 RefreshApplicationPage();
365 RefreshProcessPage();
366 RefreshPerformancePage();
367 TrayIcon_ShellUpdateTrayIcon();
368 break;
369
370 case WM_ENTERMENULOOP:
371 TaskManager_OnEnterMenuLoop(hDlg);
372 break;
373 case WM_EXITMENULOOP:
374 TaskManager_OnExitMenuLoop(hDlg);
375 break;
376 case WM_MENUSELECT:
377 TaskManager_OnMenuSelect(hDlg, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
378 break;
379 }
380
381 return 0;
382 }
383
384 void FillSolidRect(HDC hDC, LPCRECT lpRect, COLORREF clr)
385 {
386 SetBkColor(hDC, clr);
387 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
388 }
389
390 void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr)
391 {
392 RECT rect;
393
394 SetBkColor(hDC, clr);
395 rect.left = x;
396 rect.top = y;
397 rect.right = x + cx;
398 rect.bottom = y + cy;
399 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
400 }
401
402 void Draw3dRect(HDC hDC, int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
403 {
404 FillSolidRect2(hDC, x, y, cx - 1, 1, clrTopLeft);
405 FillSolidRect2(hDC, x, y, 1, cy - 1, clrTopLeft);
406 FillSolidRect2(hDC, x + cx, y, -1, cy, clrBottomRight);
407 FillSolidRect2(hDC, x, y + cy, cx, -1, clrBottomRight);
408 }
409
410 void Draw3dRect2(HDC hDC, LPRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
411 {
412 Draw3dRect(hDC, lpRect->left, lpRect->top, lpRect->right - lpRect->left,
413 lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
414 }
415
416 BOOL OnCreate(HWND hWnd)
417 {
418 HMENU hMenu;
419 HMENU hEditMenu;
420 HMENU hViewMenu;
421 HMENU hUpdateSpeedMenu;
422 HMENU hCPUHistoryMenu;
423 int nActivePage;
424 int nParts[3];
425 RECT rc;
426 WCHAR szTemp[256];
427 TCITEM item;
428
429 SendMessageW(hMainWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_TASKMANAGER)));
430
431 /* Initialize the Windows Common Controls DLL */
432 InitCommonControls();
433
434 /* Get the minimum window sizes */
435 GetWindowRect(hWnd, &rc);
436 nMinimumWidth = (rc.right - rc.left);
437 nMinimumHeight = (rc.bottom - rc.top);
438
439 /* Create the status bar */
440 hStatusWnd = CreateStatusWindow(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS, L"", hWnd, STATUS_WINDOW);
441 if(!hStatusWnd)
442 return FALSE;
443
444 /* Create the status bar panes */
445 nParts[0] = 100;
446 nParts[1] = 210;
447 nParts[2] = 400;
448 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
449
450 /* Create tab pages */
451 hTabWnd = GetDlgItem(hWnd, IDC_TAB);
452 #if 1
453 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hWnd, ApplicationPageWndProc);
454 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hWnd, ProcessPageWndProc);
455 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hWnd, PerformancePageWndProc);
456 #else
457 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hTabWnd, ApplicationPageWndProc);
458 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hTabWnd, ProcessPageWndProc);
459 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hTabWnd, PerformancePageWndProc);
460 #endif
461
462 /* Insert tabs */
463 LoadStringW(hInst, IDS_TAB_APPS, szTemp, 256);
464 memset(&item, 0, sizeof(TCITEM));
465 item.mask = TCIF_TEXT;
466 item.pszText = szTemp;
467 (void)TabCtrl_InsertItem(hTabWnd, 0, &item);
468 LoadStringW(hInst, IDS_TAB_PROCESSES, szTemp, 256);
469 memset(&item, 0, sizeof(TCITEM));
470 item.mask = TCIF_TEXT;
471 item.pszText = szTemp;
472 (void)TabCtrl_InsertItem(hTabWnd, 1, &item);
473 LoadStringW(hInst, IDS_TAB_PERFORMANCE, szTemp, 256);
474 memset(&item, 0, sizeof(TCITEM));
475 item.mask = TCIF_TEXT;
476 item.pszText = szTemp;
477 (void)TabCtrl_InsertItem(hTabWnd, 2, &item);
478
479 /* Size everything correctly */
480 GetClientRect(hWnd, &rc);
481 nOldWidth = rc.right;
482 nOldHeight = rc.bottom;
483 /* nOldStartX = rc.left; */
484 /*nOldStartY = rc.top; */
485
486 #define PAGE_OFFSET_LEFT 17
487 #define PAGE_OFFSET_TOP 72
488 #define PAGE_OFFSET_WIDTH (PAGE_OFFSET_LEFT*2)
489 #define PAGE_OFFSET_HEIGHT (PAGE_OFFSET_TOP+32)
490
491 if ((TaskManagerSettings.Left != 0) ||
492 (TaskManagerSettings.Top != 0) ||
493 (TaskManagerSettings.Right != 0) ||
494 (TaskManagerSettings.Bottom != 0))
495 {
496 MoveWindow(hWnd, TaskManagerSettings.Left, TaskManagerSettings.Top, TaskManagerSettings.Right - TaskManagerSettings.Left, TaskManagerSettings.Bottom - TaskManagerSettings.Top, TRUE);
497 #ifdef __GNUC__TEST__
498 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);
499 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);
500 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);
501 #endif
502 }
503 if (TaskManagerSettings.Maximized)
504 ShowWindow(hWnd, SW_MAXIMIZE);
505
506 /* Set the always on top style */
507 hMenu = GetMenu(hWnd);
508 hEditMenu = GetSubMenu(hMenu, 1);
509 hViewMenu = GetSubMenu(hMenu, 2);
510 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
511 hCPUHistoryMenu = GetSubMenu(hViewMenu, 7);
512
513 /* Check or uncheck the always on top menu item */
514 if (TaskManagerSettings.AlwaysOnTop) {
515 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED);
516 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
517 } else {
518 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED);
519 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
520 }
521
522 /* Check or uncheck the minimize on use menu item */
523 if (TaskManagerSettings.MinimizeOnUse)
524 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_CHECKED);
525 else
526 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_UNCHECKED);
527
528 /* Check or uncheck the hide when minimized menu item */
529 if (TaskManagerSettings.HideWhenMinimized)
530 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_CHECKED);
531 else
532 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_UNCHECKED);
533
534 /* Check or uncheck the show 16-bit tasks menu item */
535 if (TaskManagerSettings.Show16BitTasks)
536 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
537 else
538 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_UNCHECKED);
539
540 if (TaskManagerSettings.View_LargeIcons)
541 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
542 else if (TaskManagerSettings.View_SmallIcons)
543 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
544 else
545 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
546
547 if (TaskManagerSettings.ShowKernelTimes)
548 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
549 else
550 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
551
552 if (TaskManagerSettings.UpdateSpeed == 1)
553 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_HIGH, MF_BYCOMMAND);
554 else if (TaskManagerSettings.UpdateSpeed == 2)
555 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_NORMAL, MF_BYCOMMAND);
556 else if (TaskManagerSettings.UpdateSpeed == 4)
557 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_LOW, MF_BYCOMMAND);
558 else
559 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_PAUSED, MF_BYCOMMAND);
560
561 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
562 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
563 else
564 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
565
566 nActivePage = TaskManagerSettings.ActiveTabPage;
567 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 0);
568 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 1);
569 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 2);
570 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, nActivePage);
571
572 if (TaskManagerSettings.UpdateSpeed == 1)
573 SetTimer(hWnd, 1, 1000, NULL);
574 else if (TaskManagerSettings.UpdateSpeed == 2)
575 SetTimer(hWnd, 1, 2000, NULL);
576 else if (TaskManagerSettings.UpdateSpeed == 4)
577 SetTimer(hWnd, 1, 4000, NULL);
578
579 /*
580 * Refresh the performance data
581 * Sample it twice so we can establish
582 * the delta values & cpu usage
583 */
584 PerfDataRefresh();
585 PerfDataRefresh();
586
587 RefreshApplicationPage();
588 RefreshProcessPage();
589 RefreshPerformancePage();
590
591 TrayIcon_ShellAddTrayIcon();
592
593 return TRUE;
594 }
595
596 /* OnMove()
597 * This function handles all the moving events for the application
598 * It moves every child window that needs moving
599 */
600 void OnMove( WPARAM nType, int cx, int cy )
601 {
602 #ifdef __GNUC__TEST__
603 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);
604 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);
605 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);
606 #endif
607 }
608
609 /* OnSize()
610 * This function handles all the sizing events for the application
611 * It re-sizes every window, and child window that needs re-sizing
612 */
613 void OnSize( WPARAM nType, int cx, int cy )
614 {
615 int nParts[3];
616 int nXDifference;
617 int nYDifference;
618 RECT rc;
619
620 if (nType == SIZE_MINIMIZED)
621 {
622 if(TaskManagerSettings.HideWhenMinimized)
623 {
624 ShowWindow(hMainWnd, SW_HIDE);
625 }
626 return;
627 }
628
629 nXDifference = cx - nOldWidth;
630 nYDifference = cy - nOldHeight;
631 nOldWidth = cx;
632 nOldHeight = cy;
633
634 /* Update the status bar size */
635 GetWindowRect(hStatusWnd, &rc);
636 SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx, cy + (rc.bottom - rc.top)));
637
638 /* Update the status bar pane sizes */
639 nParts[0] = bInMenuLoop ? -1 : 100;
640 nParts[1] = 210;
641 nParts[2] = cx;
642 SendMessageW(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (LPARAM) (LPINT) nParts);
643
644 /* Resize the tab control */
645 GetWindowRect(hTabWnd, &rc);
646 cx = (rc.right - rc.left) + nXDifference;
647 cy = (rc.bottom - rc.top) + nYDifference;
648 SetWindowPos(hTabWnd, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
649
650 /* Resize the application page */
651 GetWindowRect(hApplicationPage, &rc);
652 cx = (rc.right - rc.left) + nXDifference;
653 cy = (rc.bottom - rc.top) + nYDifference;
654 SetWindowPos(hApplicationPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
655
656 /* Resize the process page */
657 GetWindowRect(hProcessPage, &rc);
658 cx = (rc.right - rc.left) + nXDifference;
659 cy = (rc.bottom - rc.top) + nYDifference;
660 SetWindowPos(hProcessPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
661
662 /* Resize the performance page */
663 GetWindowRect(hPerformancePage, &rc);
664 cx = (rc.right - rc.left) + nXDifference;
665 cy = (rc.bottom - rc.top) + nYDifference;
666 SetWindowPos(hPerformancePage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
667 }
668
669 void LoadSettings(void)
670 {
671 HKEY hKey;
672 WCHAR szSubKey[] = L"Software\\ReactWare\\TaskManager";
673 int i;
674 DWORD dwSize;
675
676 /* Window size & position settings */
677 TaskManagerSettings.Maximized = FALSE;
678 TaskManagerSettings.Left = 0;
679 TaskManagerSettings.Top = 0;
680 TaskManagerSettings.Right = 0;
681 TaskManagerSettings.Bottom = 0;
682
683 /* Tab settings */
684 TaskManagerSettings.ActiveTabPage = 0;
685
686 /* Options menu settings */
687 TaskManagerSettings.AlwaysOnTop = FALSE;
688 TaskManagerSettings.MinimizeOnUse = TRUE;
689 TaskManagerSettings.HideWhenMinimized = TRUE;
690 TaskManagerSettings.Show16BitTasks = TRUE;
691
692 /* Update speed settings */
693 TaskManagerSettings.UpdateSpeed = 2;
694
695 /* Applications page settings */
696 TaskManagerSettings.View_LargeIcons = FALSE;
697 TaskManagerSettings.View_SmallIcons = FALSE;
698 TaskManagerSettings.View_Details = TRUE;
699
700 /* Processes page settings */
701 TaskManagerSettings.ShowProcessesFromAllUsers = FALSE; /* Server-only? */
702
703 for (i = 0; i < COLUMN_NMAX; i++) {
704 TaskManagerSettings.Columns[i] = ColumnPresets[i].bDefaults;
705 TaskManagerSettings.ColumnOrderArray[i] = i;
706 TaskManagerSettings.ColumnSizeArray[i] = ColumnPresets[i].size;
707 }
708
709 TaskManagerSettings.SortColumn = 1;
710 TaskManagerSettings.SortAscending = TRUE;
711
712 /* Performance page settings */
713 TaskManagerSettings.CPUHistory_OneGraphPerCPU = TRUE;
714 TaskManagerSettings.ShowKernelTimes = FALSE;
715
716 /* Open the key */
717 if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
718 return;
719 /* Read the settings */
720 dwSize = sizeof(TASKMANAGER_SETTINGS);
721 RegQueryValueExW(hKey, L"Preferences", NULL, NULL, (LPBYTE)&TaskManagerSettings, &dwSize);
722
723 /*
724 * ATM, the 'ImageName' column is always visible
725 * (and grayed in configuration dialog)
726 * This will avoid troubles if the registry gets corrupted.
727 */
728 TaskManagerSettings.Column_ImageName = TRUE;
729
730 /* Close the key */
731 RegCloseKey(hKey);
732 }
733
734 void SaveSettings(void)
735 {
736 HKEY hKey;
737 WCHAR szSubKey1[] = L"Software";
738 WCHAR szSubKey2[] = L"Software\\ReactWare";
739 WCHAR szSubKey3[] = L"Software\\ReactWare\\TaskManager";
740
741 /* Open (or create) the key */
742 hKey = NULL;
743 RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey1, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
744 RegCloseKey(hKey);
745 hKey = NULL;
746 RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey2, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
747 RegCloseKey(hKey);
748 hKey = NULL;
749 if (RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey3, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
750 return;
751 /* Save the settings */
752 RegSetValueExW(hKey, L"Preferences", 0, REG_BINARY, (LPBYTE)&TaskManagerSettings, sizeof(TASKMANAGER_SETTINGS));
753 /* Close the key */
754 RegCloseKey(hKey);
755 }
756
757 void TaskManager_OnRestoreMainWindow(void)
758 {
759 HMENU hMenu, hOptionsMenu;
760 BOOL OnTop;
761
762 hMenu = GetMenu(hMainWnd);
763 hOptionsMenu = GetSubMenu(hMenu, OPTIONS_MENU_INDEX);
764 OnTop = ((GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
765
766 OpenIcon(hMainWnd);
767 SetForegroundWindow(hMainWnd);
768 SetWindowPos(hMainWnd, (OnTop ? HWND_TOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
769 }
770
771 void TaskManager_OnEnterMenuLoop(HWND hWnd)
772 {
773 int nParts;
774
775 /* Update the status bar pane sizes */
776 nParts = -1;
777 SendMessageW(hStatusWnd, SB_SETPARTS, 1, (LPARAM) (LPINT)&nParts);
778 bInMenuLoop = TRUE;
779 SendMessageW(hStatusWnd, SB_SETTEXT, (WPARAM)0, (LPARAM)L"");
780 }
781
782 void TaskManager_OnExitMenuLoop(HWND hWnd)
783 {
784 RECT rc;
785 int nParts[3];
786 WCHAR text[260];
787 WCHAR szCpuUsage[256], szProcesses[256];
788
789 LoadStringW(hInst, IDS_STATUS_CPUUSAGE, szCpuUsage, 256);
790 LoadStringW(hInst, IDS_STATUS_PROCESSES, szProcesses, 256);
791
792 bInMenuLoop = FALSE;
793 /* Update the status bar pane sizes */
794 GetClientRect(hWnd, &rc);
795 nParts[0] = 100;
796 nParts[1] = 210;
797 nParts[2] = rc.right;
798 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
799 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)L"");
800 wsprintfW(text, szCpuUsage, PerfDataGetProcessorUsage());
801 SendMessageW(hStatusWnd, SB_SETTEXT, 1, (LPARAM)text);
802 wsprintfW(text, szProcesses, PerfDataGetProcessCount());
803 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)text);
804 }
805
806 void TaskManager_OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
807 {
808 WCHAR str[100];
809
810 wcscpy(str, L"");
811 if (LoadStringW(hInst, nItemID, str, 100)) {
812 /* load appropriate string */
813 LPWSTR lpsz = str;
814 /* first newline terminates actual string */
815 lpsz = wcschr(lpsz, '\n');
816 if (lpsz != NULL)
817 *lpsz = '\0';
818 }
819 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)str);
820 }
821
822 void TaskManager_OnViewUpdateSpeedHigh(void)
823 {
824 HMENU hMenu;
825 HMENU hViewMenu;
826 HMENU hUpdateSpeedMenu;
827
828 hMenu = GetMenu(hMainWnd);
829 hViewMenu = GetSubMenu(hMenu, 2);
830 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
831
832 TaskManagerSettings.UpdateSpeed = 1;
833 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_HIGH, MF_BYCOMMAND);
834
835 KillTimer(hMainWnd, 1);
836 SetTimer(hMainWnd, 1, 500, NULL);
837 }
838
839 void TaskManager_OnViewUpdateSpeedNormal(void)
840 {
841 HMENU hMenu;
842 HMENU hViewMenu;
843 HMENU hUpdateSpeedMenu;
844
845 hMenu = GetMenu(hMainWnd);
846 hViewMenu = GetSubMenu(hMenu, 2);
847 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
848
849 TaskManagerSettings.UpdateSpeed = 2;
850 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_NORMAL, MF_BYCOMMAND);
851
852 KillTimer(hMainWnd, 1);
853 SetTimer(hMainWnd, 1, 2000, NULL);
854 }
855
856 void TaskManager_OnViewUpdateSpeedLow(void)
857 {
858 HMENU hMenu;
859 HMENU hViewMenu;
860 HMENU hUpdateSpeedMenu;
861
862 hMenu = GetMenu(hMainWnd);
863 hViewMenu = GetSubMenu(hMenu, 2);
864 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
865
866 TaskManagerSettings.UpdateSpeed = 4;
867 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_LOW, MF_BYCOMMAND);
868
869 KillTimer(hMainWnd, 1);
870 SetTimer(hMainWnd, 1, 4000, NULL);
871 }
872
873 void TaskManager_OnViewRefresh(void)
874 {
875 PostMessageW(hMainWnd, WM_TIMER, 0, 0);
876 }
877
878 void TaskManager_OnViewUpdateSpeedPaused(void)
879 {
880 HMENU hMenu;
881 HMENU hViewMenu;
882 HMENU hUpdateSpeedMenu;
883
884 hMenu = GetMenu(hMainWnd);
885 hViewMenu = GetSubMenu(hMenu, 2);
886 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
887 TaskManagerSettings.UpdateSpeed = 0;
888 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_PAUSED, MF_BYCOMMAND);
889 KillTimer(hMainWnd, 1);
890 }
891
892 void TaskManager_OnTabWndSelChange(void)
893 {
894 int i;
895 HMENU hMenu;
896 HMENU hOptionsMenu;
897 HMENU hViewMenu;
898 HMENU hSubMenu;
899 WCHAR szTemp[256];
900
901 hMenu = GetMenu(hMainWnd);
902 hViewMenu = GetSubMenu(hMenu, 2);
903 hOptionsMenu = GetSubMenu(hMenu, 1);
904 TaskManagerSettings.ActiveTabPage = TabCtrl_GetCurSel(hTabWnd);
905 for (i = GetMenuItemCount(hViewMenu) - 1; i > 2; i--) {
906 hSubMenu = GetSubMenu(hViewMenu, i);
907 if (hSubMenu)
908 DestroyMenu(hSubMenu);
909 RemoveMenu(hViewMenu, i, MF_BYPOSITION);
910 }
911 RemoveMenu(hOptionsMenu, 3, MF_BYPOSITION);
912 switch (TaskManagerSettings.ActiveTabPage) {
913 case 0:
914 ShowWindow(hApplicationPage, SW_SHOW);
915 ShowWindow(hProcessPage, SW_HIDE);
916 ShowWindow(hPerformancePage, SW_HIDE);
917 BringWindowToTop(hApplicationPage);
918
919 LoadStringW(hInst, IDS_MENU_LARGEICONS, szTemp, 256);
920 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_LARGE, szTemp);
921
922 LoadStringW(hInst, IDS_MENU_SMALLICONS, szTemp, 256);
923 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SMALL, szTemp);
924
925 LoadStringW(hInst, IDS_MENU_DETAILS, szTemp, 256);
926 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_DETAILS, szTemp);
927
928 if (GetMenuItemCount(hMenu) <= 4) {
929 hSubMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_WINDOWSMENU));
930
931 LoadStringW(hInst, IDS_MENU_WINDOWS, szTemp, 256);
932 InsertMenuW(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
933
934 DrawMenuBar(hMainWnd);
935 }
936 if (TaskManagerSettings.View_LargeIcons)
937 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
938 else if (TaskManagerSettings.View_SmallIcons)
939 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
940 else
941 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
942 /*
943 * Give the application list control focus
944 */
945 SetFocus(hApplicationPageListCtrl);
946 break;
947
948 case 1:
949 ShowWindow(hApplicationPage, SW_HIDE);
950 ShowWindow(hProcessPage, SW_SHOW);
951 ShowWindow(hPerformancePage, SW_HIDE);
952 BringWindowToTop(hProcessPage);
953
954 LoadStringW(hInst, IDS_MENU_SELECTCOLUMNS, szTemp, 256);
955 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, szTemp);
956
957 LoadStringW(hInst, IDS_MENU_16BITTASK, szTemp, 256);
958 AppendMenuW(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, szTemp);
959
960 if (TaskManagerSettings.Show16BitTasks)
961 CheckMenuItem(hOptionsMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
962 if (GetMenuItemCount(hMenu) > 4)
963 {
964 DeleteMenu(hMenu, 3, MF_BYPOSITION);
965 DrawMenuBar(hMainWnd);
966 }
967 /*
968 * Give the process list control focus
969 */
970 SetFocus(hProcessPageListCtrl);
971 break;
972
973 case 2:
974 ShowWindow(hApplicationPage, SW_HIDE);
975 ShowWindow(hProcessPage, SW_HIDE);
976 ShowWindow(hPerformancePage, SW_SHOW);
977 BringWindowToTop(hPerformancePage);
978 if (GetMenuItemCount(hMenu) > 4) {
979 DeleteMenu(hMenu, 3, MF_BYPOSITION);
980 DrawMenuBar(hMainWnd);
981 }
982 hSubMenu = CreatePopupMenu();
983
984 LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
985 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
986
987 LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
988 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
989
990 LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
991 AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
992
993 LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256);
994 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp);
995
996 if (TaskManagerSettings.ShowKernelTimes)
997 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
998 else
999 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
1000 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
1001 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
1002 else
1003 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
1004 /*
1005 * Give the tab control focus
1006 */
1007 SetFocus(hTabWnd);
1008 break;
1009 }
1010 }
1011
1012 LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize)
1013 {
1014 DWORD dwRet;
1015 LPWSTR lpszTemp = NULL;
1016
1017 dwRet = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
1018 NULL,
1019 GetLastError(),
1020 LANG_NEUTRAL,
1021 (LPWSTR)&lpszTemp,
1022 0,
1023 NULL );
1024
1025 /* supplied buffer is not long enough */
1026 if (!dwRet || ( (long)dwSize < (long)dwRet+14)) {
1027 lpszBuf[0] = L'\0';
1028 } else {
1029 lpszTemp[lstrlenW(lpszTemp)-2] = L'\0'; /*remove cr and newline character */
1030 wsprintfW(lpszBuf, L"%s (0x%x)", lpszTemp, (int)GetLastError());
1031 }
1032 if (lpszTemp) {
1033 LocalFree((HLOCAL)lpszTemp);
1034 }
1035 return lpszBuf;
1036 }