1 /*
2  * PROJECT:     ReactOS Task Manager
3  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4  * PURPOSE:     Performance Page
5  * COPYRIGHT:   Copyright 1999-2001 Brian Palmer <brianp@reactos.org>
6  */
7 
8 #include "precomp.h"
9 #include <shlwapi.h>
10 
11 TM_GRAPH_CONTROL PerformancePageCpuUsageHistoryGraph;
12 TM_GRAPH_CONTROL PerformancePageMemUsageHistoryGraph;
13 
14 HWND hPerformancePage;                /* Performance Property Page */
15 static HWND hCpuUsageGraph;                  /* CPU Usage Graph */
16 static HWND hMemUsageGraph;                  /* MEM Usage Graph */
17 HWND hPerformancePageCpuUsageHistoryGraph;           /* CPU Usage History Graph */
18 HWND hPerformancePageMemUsageHistoryGraph;           /* Memory Usage History Graph */
19 static HWND hTotalsFrame;                    /* Totals Frame */
20 static HWND hCommitChargeFrame;              /* Commit Charge Frame */
21 static HWND hKernelMemoryFrame;              /* Kernel Memory Frame */
22 static HWND hPhysicalMemoryFrame;            /* Physical Memory Frame */
23 static HWND hCpuUsageFrame;
24 static HWND hMemUsageFrame;
25 static HWND hCpuUsageHistoryFrame;
26 static HWND hMemUsageHistoryFrame;
27 static HWND hCommitChargeTotalEdit;          /* Commit Charge Total Edit Control */
28 static HWND hCommitChargeLimitEdit;          /* Commit Charge Limit Edit Control */
29 static HWND hCommitChargePeakEdit;           /* Commit Charge Peak Edit Control */
30 static HWND hKernelMemoryTotalEdit;          /* Kernel Memory Total Edit Control */
31 static HWND hKernelMemoryPagedEdit;          /* Kernel Memory Paged Edit Control */
32 static HWND hKernelMemoryNonPagedEdit;       /* Kernel Memory NonPaged Edit Control */
33 static HWND hPhysicalMemoryTotalEdit;        /* Physical Memory Total Edit Control */
34 static HWND hPhysicalMemoryAvailableEdit;    /* Physical Memory Available Edit Control */
35 static HWND hPhysicalMemorySystemCacheEdit;  /* Physical Memory System Cache Edit Control */
36 static HWND hTotalsHandleCountEdit;          /* Total Handles Edit Control */
37 static HWND hTotalsProcessCountEdit;         /* Total Processes Edit Control */
38 static HWND hTotalsThreadCountEdit;          /* Total Threads Edit Control */
39 
40 #ifdef RUN_PERF_PAGE
41 static HANDLE hPerformanceThread = NULL;
42 static DWORD  dwPerformanceThread;
43 #endif
44 
45 static int nPerformancePageWidth;
46 static int nPerformancePageHeight;
47 static int lastX, lastY;
48 DWORD WINAPI PerformancePageRefreshThread(PVOID Parameter);
49 
AdjustFrameSize(HWND hCntrl,HWND hDlg,int nXDifference,int nYDifference,int pos)50 void AdjustFrameSize(HWND hCntrl, HWND hDlg, int nXDifference, int nYDifference, int pos)
51 {
52     RECT  rc;
53     int   cx, cy, sx, sy;
54 
55     GetClientRect(hCntrl, &rc);
56     MapWindowPoints(hCntrl, hDlg, (LPPOINT)(PRECT)(&rc), sizeof(RECT)/sizeof(POINT));
57     if (pos) {
58         cx = rc.left;
59         cy = rc.top;
60         sx = rc.right - rc.left;
61         switch (pos) {
62         case 1:
63             break;
64         case 2:
65             cy += nYDifference / 2;
66             break;
67         case 3:
68             sx += nXDifference;
69             break;
70         case 4:
71             cy += nYDifference / 2;
72             sx += nXDifference;
73             break;
74         }
75         sy = rc.bottom - rc.top + nYDifference / 2;
76         SetWindowPos(hCntrl, NULL, cx, cy, sx, sy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER);
77     } else {
78         cx = rc.left + nXDifference;
79         cy = rc.top + nYDifference;
80         SetWindowPos(hCntrl, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
81     }
82     InvalidateRect(hCntrl, NULL, TRUE);
83 }
84 
85 static inline
AdjustControlPosition(HWND hCntrl,HWND hDlg,int nXDifference,int nYDifference)86 void AdjustControlPosition(HWND hCntrl, HWND hDlg, int nXDifference, int nYDifference)
87 {
88     AdjustFrameSize(hCntrl, hDlg, nXDifference, nYDifference, 0);
89 }
90 
91 static inline
AdjustCntrlPos(int ctrl_id,HWND hDlg,int nXDifference,int nYDifference)92 void AdjustCntrlPos(int ctrl_id, HWND hDlg, int nXDifference, int nYDifference)
93 {
94     AdjustFrameSize(GetDlgItem(hDlg, ctrl_id), hDlg, nXDifference, nYDifference, 0);
95 }
96 
97 INT_PTR CALLBACK
PerformancePageWndProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)98 PerformancePageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
99 {
100     RECT rc;
101 
102     switch (message)
103     {
104         case WM_DESTROY:
105             GraphCtrl_Dispose(&PerformancePageCpuUsageHistoryGraph);
106             GraphCtrl_Dispose(&PerformancePageMemUsageHistoryGraph);
107 #ifdef RUN_PERF_PAGE
108             EndLocalThread(&hPerformanceThread, dwPerformanceThread);
109 #endif
110             break;
111 
112         case WM_INITDIALOG:
113         {
114             BOOL bGraph;
115             TM_FORMAT fmt;
116 
117             /* Save the width and height */
118             GetClientRect(hDlg, &rc);
119             nPerformancePageWidth = rc.right;
120             nPerformancePageHeight = rc.bottom;
121 
122             /* Update window position */
123             SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
124 
125             /*
126              * Get handles to all the controls
127              */
128             hTotalsFrame = GetDlgItem(hDlg, IDC_TOTALS_FRAME);
129             hCommitChargeFrame = GetDlgItem(hDlg, IDC_COMMIT_CHARGE_FRAME);
130             hKernelMemoryFrame = GetDlgItem(hDlg, IDC_KERNEL_MEMORY_FRAME);
131             hPhysicalMemoryFrame = GetDlgItem(hDlg, IDC_PHYSICAL_MEMORY_FRAME);
132 
133             hCpuUsageFrame = GetDlgItem(hDlg, IDC_CPU_USAGE_FRAME);
134             hMemUsageFrame = GetDlgItem(hDlg, IDC_MEM_USAGE_FRAME);
135             hCpuUsageHistoryFrame = GetDlgItem(hDlg, IDC_CPU_USAGE_HISTORY_FRAME);
136             hMemUsageHistoryFrame = GetDlgItem(hDlg, IDC_MEMORY_USAGE_HISTORY_FRAME);
137 
138             hCommitChargeTotalEdit = GetDlgItem(hDlg, IDC_COMMIT_CHARGE_TOTAL);
139             hCommitChargeLimitEdit = GetDlgItem(hDlg, IDC_COMMIT_CHARGE_LIMIT);
140             hCommitChargePeakEdit = GetDlgItem(hDlg, IDC_COMMIT_CHARGE_PEAK);
141             hKernelMemoryTotalEdit = GetDlgItem(hDlg, IDC_KERNEL_MEMORY_TOTAL);
142             hKernelMemoryPagedEdit = GetDlgItem(hDlg, IDC_KERNEL_MEMORY_PAGED);
143             hKernelMemoryNonPagedEdit = GetDlgItem(hDlg, IDC_KERNEL_MEMORY_NONPAGED);
144             hPhysicalMemoryTotalEdit = GetDlgItem(hDlg, IDC_PHYSICAL_MEMORY_TOTAL);
145             hPhysicalMemoryAvailableEdit = GetDlgItem(hDlg, IDC_PHYSICAL_MEMORY_AVAILABLE);
146             hPhysicalMemorySystemCacheEdit = GetDlgItem(hDlg, IDC_PHYSICAL_MEMORY_SYSTEM_CACHE);
147             hTotalsHandleCountEdit = GetDlgItem(hDlg, IDC_TOTALS_HANDLE_COUNT);
148             hTotalsProcessCountEdit = GetDlgItem(hDlg, IDC_TOTALS_PROCESS_COUNT);
149             hTotalsThreadCountEdit = GetDlgItem(hDlg, IDC_TOTALS_THREAD_COUNT);
150 
151             hCpuUsageGraph = GetDlgItem(hDlg, IDC_CPU_USAGE_GRAPH);
152             hMemUsageGraph = GetDlgItem(hDlg, IDC_MEM_USAGE_GRAPH);
153             hPerformancePageMemUsageHistoryGraph = GetDlgItem(hDlg, IDC_MEM_USAGE_HISTORY_GRAPH);
154             hPerformancePageCpuUsageHistoryGraph = GetDlgItem(hDlg, IDC_CPU_USAGE_HISTORY_GRAPH);
155 
156             /* Create the controls */
157             fmt.clrBack = RGB(0, 0, 0);
158             fmt.clrGrid = RGB(0, 128, 64);
159             fmt.clrPlot0 = RGB(0, 255, 0);
160             fmt.clrPlot1 = RGB(255, 0, 0);
161             fmt.GridCellWidth = fmt.GridCellHeight = 12;
162             fmt.DrawSecondaryPlot = TaskManagerSettings.ShowKernelTimes;
163             bGraph = GraphCtrl_Create(&PerformancePageCpuUsageHistoryGraph, hPerformancePageCpuUsageHistoryGraph, hDlg, &fmt);
164             if (!bGraph)
165             {
166                 EndDialog(hDlg, 0);
167                 return FALSE;
168             }
169 
170             fmt.clrPlot0 = RGB(255, 255, 0);
171             fmt.clrPlot1 = RGB(100, 255, 255);
172             fmt.DrawSecondaryPlot = TRUE;
173             bGraph = GraphCtrl_Create(&PerformancePageMemUsageHistoryGraph, hPerformancePageMemUsageHistoryGraph, hDlg, &fmt);
174             if (!bGraph)
175             {
176                 EndDialog(hDlg, 0);
177                 return FALSE;
178             }
179 
180             /* Start our refresh thread */
181 #ifdef RUN_PERF_PAGE
182             hPerformanceThread = CreateThread(NULL, 0, PerformancePageRefreshThread, NULL, 0, &dwPerformanceThread);
183 #endif
184 
185             /*
186              * Subclass graph buttons
187              */
188             OldGraphWndProc = (WNDPROC)SetWindowLongPtrW(hCpuUsageGraph, GWLP_WNDPROC, (LONG_PTR)Graph_WndProc);
189             SetWindowLongPtrW(hMemUsageGraph, GWLP_WNDPROC, (LONG_PTR)Graph_WndProc);
190             OldGraphCtrlWndProc = (WNDPROC)SetWindowLongPtrW(hPerformancePageMemUsageHistoryGraph, GWLP_WNDPROC, (LONG_PTR)GraphCtrl_WndProc);
191             SetWindowLongPtrW(hPerformancePageCpuUsageHistoryGraph, GWLP_WNDPROC, (LONG_PTR)GraphCtrl_WndProc);
192             return TRUE;
193         }
194 
195         case WM_COMMAND:
196             break;
197 
198         case WM_SIZE:
199         {
200             int  cx, cy;
201             int  nXDifference;
202             int  nYDifference;
203 
204             if (wParam == SIZE_MINIMIZED)
205                 return 0;
206 
207             cx = LOWORD(lParam);
208             cy = HIWORD(lParam);
209             nXDifference = cx - nPerformancePageWidth;
210             nYDifference = cy - nPerformancePageHeight;
211             nPerformancePageWidth = cx;
212             nPerformancePageHeight = cy;
213 
214             /* Reposition the performance page's controls */
215             AdjustFrameSize(hTotalsFrame, hDlg, 0, nYDifference, 0);
216             AdjustFrameSize(hCommitChargeFrame, hDlg, 0, nYDifference, 0);
217             AdjustFrameSize(hKernelMemoryFrame, hDlg, 0, nYDifference, 0);
218             AdjustFrameSize(hPhysicalMemoryFrame, hDlg, 0, nYDifference, 0);
219             AdjustCntrlPos(IDS_COMMIT_CHARGE_TOTAL, hDlg, 0, nYDifference);
220             AdjustCntrlPos(IDS_COMMIT_CHARGE_LIMIT, hDlg, 0, nYDifference);
221             AdjustCntrlPos(IDS_COMMIT_CHARGE_PEAK, hDlg, 0, nYDifference);
222             AdjustCntrlPos(IDS_KERNEL_MEMORY_TOTAL, hDlg, 0, nYDifference);
223             AdjustCntrlPos(IDS_KERNEL_MEMORY_PAGED, hDlg, 0, nYDifference);
224             AdjustCntrlPos(IDS_KERNEL_MEMORY_NONPAGED, hDlg, 0, nYDifference);
225             AdjustCntrlPos(IDS_PHYSICAL_MEMORY_TOTAL, hDlg, 0, nYDifference);
226             AdjustCntrlPos(IDS_PHYSICAL_MEMORY_AVAILABLE, hDlg, 0, nYDifference);
227             AdjustCntrlPos(IDS_PHYSICAL_MEMORY_SYSTEM_CACHE, hDlg, 0, nYDifference);
228             AdjustCntrlPos(IDS_TOTALS_HANDLE_COUNT, hDlg, 0, nYDifference);
229             AdjustCntrlPos(IDS_TOTALS_PROCESS_COUNT, hDlg, 0, nYDifference);
230             AdjustCntrlPos(IDS_TOTALS_THREAD_COUNT, hDlg, 0, nYDifference);
231 
232             AdjustControlPosition(hCommitChargeTotalEdit, hDlg, 0, nYDifference);
233             AdjustControlPosition(hCommitChargeLimitEdit, hDlg, 0, nYDifference);
234             AdjustControlPosition(hCommitChargePeakEdit, hDlg, 0, nYDifference);
235             AdjustControlPosition(hKernelMemoryTotalEdit, hDlg, 0, nYDifference);
236             AdjustControlPosition(hKernelMemoryPagedEdit, hDlg, 0, nYDifference);
237             AdjustControlPosition(hKernelMemoryNonPagedEdit, hDlg, 0, nYDifference);
238             AdjustControlPosition(hPhysicalMemoryTotalEdit, hDlg, 0, nYDifference);
239             AdjustControlPosition(hPhysicalMemoryAvailableEdit, hDlg, 0, nYDifference);
240             AdjustControlPosition(hPhysicalMemorySystemCacheEdit, hDlg, 0, nYDifference);
241             AdjustControlPosition(hTotalsHandleCountEdit, hDlg, 0, nYDifference);
242             AdjustControlPosition(hTotalsProcessCountEdit, hDlg, 0, nYDifference);
243             AdjustControlPosition(hTotalsThreadCountEdit, hDlg, 0, nYDifference);
244 
245             nXDifference += lastX;
246             nYDifference += lastY;
247             lastX = lastY = 0;
248             if (nXDifference % 2)
249             {
250                 if (nXDifference > 0)
251                 {
252                     nXDifference--;
253                     lastX++;
254                 }
255                 else
256                 {
257                     nXDifference++;
258                     lastX--;
259                 }
260             }
261             if (nYDifference % 2)
262             {
263                 if (nYDifference > 0)
264                 {
265                     nYDifference--;
266                     lastY++;
267                 }
268                 else
269                 {
270                     nYDifference++;
271                     lastY--;
272                 }
273             }
274             AdjustFrameSize(hCpuUsageFrame, hDlg, nXDifference, nYDifference, 1);
275             AdjustFrameSize(hMemUsageFrame, hDlg, nXDifference, nYDifference, 2);
276             AdjustFrameSize(hCpuUsageHistoryFrame, hDlg, nXDifference, nYDifference, 3);
277             AdjustFrameSize(hMemUsageHistoryFrame, hDlg, nXDifference, nYDifference, 4);
278             AdjustFrameSize(hCpuUsageGraph, hDlg, nXDifference, nYDifference, 1);
279             AdjustFrameSize(hMemUsageGraph, hDlg, nXDifference, nYDifference, 2);
280             AdjustFrameSize(hPerformancePageCpuUsageHistoryGraph, hDlg, nXDifference, nYDifference, 3);
281             AdjustFrameSize(hPerformancePageMemUsageHistoryGraph, hDlg, nXDifference, nYDifference, 4);
282             break;
283         }
284     }
285     return 0;
286 }
287 
RefreshPerformancePage(void)288 void RefreshPerformancePage(void)
289 {
290 #ifdef RUN_PERF_PAGE
291     /* Signal the event so that our refresh thread
292      * will wake up and refresh the performance page */
293     PostThreadMessage(dwPerformanceThread, WM_TIMER, 0, 0);
294 #endif
295 }
296 
PerformancePageRefreshThread(PVOID Parameter)297 DWORD WINAPI PerformancePageRefreshThread(PVOID Parameter)
298 {
299     ULONGLONG CommitChargeTotal;
300     ULONGLONG CommitChargeLimit;
301     ULONGLONG CommitChargePeak;
302 
303     ULONG CpuUsage;
304     ULONG CpuKernelUsage;
305 
306     ULONGLONG KernelMemoryTotal;
307     ULONGLONG KernelMemoryPaged;
308     ULONGLONG KernelMemoryNonPaged;
309 
310     ULONGLONG PhysicalMemoryTotal;
311     ULONGLONG PhysicalMemoryAvailable;
312     ULONGLONG PhysicalMemorySystemCache;
313 
314     ULONG TotalHandles;
315     ULONG TotalThreads;
316     ULONG TotalProcesses;
317 
318     MSG msg;
319 
320     WCHAR Text[260];
321     WCHAR szMemUsage[256], szCpuUsage[256], szProcesses[256];
322 
323     LoadStringW(hInst, IDS_STATUS_CPUUSAGE, szCpuUsage, _countof(szCpuUsage));
324     LoadStringW(hInst, IDS_STATUS_MEMUSAGE, szMemUsage, _countof(szMemUsage));
325     LoadStringW(hInst, IDS_STATUS_PROCESSES, szProcesses, _countof(szProcesses));
326 
327     while (1)
328     {
329         extern BOOL bTrackMenu; // From taskmgr.c
330 
331         int nBarsUsed1;
332         int nBarsUsed2;
333 
334         WCHAR szChargeTotalFormat[256];
335         WCHAR szChargeLimitFormat[256];
336 
337         /* Wait for an the event or application close */
338         if (GetMessage(&msg, NULL, 0, 0) <= 0)
339             return 0;
340 
341         if (msg.message == WM_TIMER)
342         {
343             /*
344              * Update the commit charge info
345              */
346             CommitChargeTotal = PerfDataGetCommitChargeTotalK();
347             CommitChargeLimit = PerfDataGetCommitChargeLimitK();
348             CommitChargePeak  = PerfDataGetCommitChargePeakK();
349             _ultow(CommitChargeTotal, Text, 10);
350             SetWindowTextW(hCommitChargeTotalEdit, Text);
351             _ultow(CommitChargeLimit, Text, 10);
352             SetWindowTextW(hCommitChargeLimitEdit, Text);
353             _ultow(CommitChargePeak, Text, 10);
354             SetWindowTextW(hCommitChargePeakEdit, Text);
355 
356             StrFormatByteSizeW(CommitChargeTotal * 1024,
357                                szChargeTotalFormat,
358                                _countof(szChargeTotalFormat));
359 
360             StrFormatByteSizeW(CommitChargeLimit * 1024,
361                                szChargeLimitFormat,
362                                _countof(szChargeLimitFormat));
363 
364             if (!bTrackMenu)
365             {
366                 wsprintfW(Text, szMemUsage, szChargeTotalFormat, szChargeLimitFormat,
367                     (CommitChargeLimit ? ((CommitChargeTotal * 100) / CommitChargeLimit) : 0));
368                 SendMessageW(hStatusWnd, SB_SETTEXT, 2, (LPARAM)Text);
369             }
370 
371             /*
372              * Update the kernel memory info
373              */
374             KernelMemoryTotal = PerfDataGetKernelMemoryTotalK();
375             KernelMemoryPaged = PerfDataGetKernelMemoryPagedK();
376             KernelMemoryNonPaged = PerfDataGetKernelMemoryNonPagedK();
377             _ultow(KernelMemoryTotal, Text, 10);
378             SetWindowTextW(hKernelMemoryTotalEdit, Text);
379             _ultow(KernelMemoryPaged, Text, 10);
380             SetWindowTextW(hKernelMemoryPagedEdit, Text);
381             _ultow(KernelMemoryNonPaged, Text, 10);
382             SetWindowTextW(hKernelMemoryNonPagedEdit, Text);
383 
384             /*
385              * Update the physical memory info
386              */
387             PhysicalMemoryTotal = PerfDataGetPhysicalMemoryTotalK();
388             PhysicalMemoryAvailable = PerfDataGetPhysicalMemoryAvailableK();
389             PhysicalMemorySystemCache = PerfDataGetPhysicalMemorySystemCacheK();
390             _ultow(PhysicalMemoryTotal, Text, 10);
391             SetWindowTextW(hPhysicalMemoryTotalEdit, Text);
392             _ultow(PhysicalMemoryAvailable, Text, 10);
393             SetWindowTextW(hPhysicalMemoryAvailableEdit, Text);
394             _ultow(PhysicalMemorySystemCache, Text, 10);
395             SetWindowTextW(hPhysicalMemorySystemCacheEdit, Text);
396 
397             /*
398              * Update the totals info
399              */
400             TotalHandles = PerfDataGetSystemHandleCount();
401             TotalThreads = PerfDataGetTotalThreadCount();
402             TotalProcesses = PerfDataGetProcessCount();
403             _ultow(TotalHandles, Text, 10);
404             SetWindowTextW(hTotalsHandleCountEdit, Text);
405             _ultow(TotalThreads, Text, 10);
406             SetWindowTextW(hTotalsThreadCountEdit, Text);
407             _ultow(TotalProcesses, Text, 10);
408             SetWindowTextW(hTotalsProcessCountEdit, Text);
409             if (!bTrackMenu)
410             {
411                 wsprintfW(Text, szProcesses, TotalProcesses);
412                 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)Text);
413             }
414 
415             /*
416              * Redraw the graphs
417              */
418             InvalidateRect(hCpuUsageGraph, NULL, FALSE);
419             InvalidateRect(hMemUsageGraph, NULL, FALSE);
420 
421             /*
422              * Get the CPU usage
423              */
424             CpuUsage = PerfDataGetProcessorUsage();
425             CpuKernelUsage = PerfDataGetProcessorSystemUsage();
426 
427             if (!bTrackMenu)
428             {
429                 wsprintfW(Text, szCpuUsage, CpuUsage);
430                 SendMessageW(hStatusWnd, SB_SETTEXT, 1, (LPARAM)Text);
431             }
432 
433             /*
434              * Get the memory usage
435              */
436             CommitChargeTotal = PerfDataGetCommitChargeTotalK();
437             CommitChargeLimit = PerfDataGetCommitChargeLimitK();
438             nBarsUsed1 = CommitChargeLimit ? ((CommitChargeTotal * 100) / CommitChargeLimit) : 0;
439 
440             PhysicalMemoryTotal = PerfDataGetPhysicalMemoryTotalK();
441             PhysicalMemoryAvailable = PerfDataGetPhysicalMemoryAvailableK();
442             nBarsUsed2 = PhysicalMemoryTotal ? ((PhysicalMemoryAvailable * 100) / PhysicalMemoryTotal) : 0;
443 
444             GraphCtrl_AddPoint(&PerformancePageCpuUsageHistoryGraph, CpuUsage, CpuKernelUsage);
445             GraphCtrl_AddPoint(&PerformancePageMemUsageHistoryGraph, nBarsUsed1, nBarsUsed2);
446             InvalidateRect(hPerformancePageMemUsageHistoryGraph, NULL, FALSE);
447             InvalidateRect(hPerformancePageCpuUsageHistoryGraph, NULL, FALSE);
448         }
449     }
450     return 0;
451 }
452 
PerformancePage_OnViewShowKernelTimes(void)453 void PerformancePage_OnViewShowKernelTimes(void)
454 {
455     HMENU hMenu;
456     HMENU hViewMenu;
457 
458     hMenu = GetMenu(hMainWnd);
459     hViewMenu = GetSubMenu(hMenu, 2);
460 
461     /* Check or uncheck the show 16-bit tasks menu item */
462     if (GetMenuState(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND) & MF_CHECKED)
463     {
464         CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
465         TaskManagerSettings.ShowKernelTimes = FALSE;
466         PerformancePageCpuUsageHistoryGraph.DrawSecondaryPlot = FALSE;
467     }
468     else
469     {
470         CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
471         TaskManagerSettings.ShowKernelTimes = TRUE;
472         PerformancePageCpuUsageHistoryGraph.DrawSecondaryPlot = TRUE;
473     }
474 
475     GraphCtrl_RedrawBitmap(&PerformancePageCpuUsageHistoryGraph, PerformancePageCpuUsageHistoryGraph.BitmapHeight);
476     RefreshPerformancePage();
477 }
478 
PerformancePage_OnViewCPUHistoryOneGraphAll(void)479 void PerformancePage_OnViewCPUHistoryOneGraphAll(void)
480 {
481     HMENU hMenu;
482     HMENU hViewMenu;
483     HMENU hCPUHistoryMenu;
484 
485     hMenu = GetMenu(hMainWnd);
486     hViewMenu = GetSubMenu(hMenu, 2);
487     hCPUHistoryMenu = GetSubMenu(hViewMenu, 3);
488 
489     TaskManagerSettings.CPUHistory_OneGraphPerCPU = FALSE;
490     CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
491 }
492 
PerformancePage_OnViewCPUHistoryOneGraphPerCPU(void)493 void PerformancePage_OnViewCPUHistoryOneGraphPerCPU(void)
494 {
495     HMENU hMenu;
496     HMENU hViewMenu;
497     HMENU hCPUHistoryMenu;
498 
499     hMenu = GetMenu(hMainWnd);
500     hViewMenu = GetSubMenu(hMenu, 2);
501     hCPUHistoryMenu = GetSubMenu(hViewMenu, 3);
502 
503     TaskManagerSettings.CPUHistory_OneGraphPerCPU = TRUE;
504     CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
505 }
506