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 Graph Meters.
5 * COPYRIGHT: Copyright 1999-2001 Brian Palmer <brianp@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 int nlastBarsUsed = 0;
11
12 WNDPROC OldGraphWndProc;
13
14 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd);
15 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd);
16 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd);
17
18 INT_PTR CALLBACK
Graph_WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)19 Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
20 {
21 HDC hdc;
22 PAINTSTRUCT ps;
23 LONG WindowId;
24
25 switch (message)
26 {
27 case WM_ERASEBKGND:
28 return TRUE;
29
30 /*
31 * Filter out mouse & keyboard messages
32 */
33 /* case WM_APPCOMMAND: */
34 case WM_CAPTURECHANGED:
35 case WM_LBUTTONDBLCLK:
36 case WM_LBUTTONDOWN:
37 case WM_LBUTTONUP:
38 case WM_MBUTTONDBLCLK:
39 case WM_MBUTTONDOWN:
40 case WM_MBUTTONUP:
41 case WM_MOUSEACTIVATE:
42 case WM_MOUSEHOVER:
43 case WM_MOUSELEAVE:
44 case WM_MOUSEMOVE:
45 /* case WM_MOUSEWHEEL: */
46 case WM_NCHITTEST:
47 case WM_NCLBUTTONDBLCLK:
48 case WM_NCLBUTTONDOWN:
49 case WM_NCLBUTTONUP:
50 case WM_NCMBUTTONDBLCLK:
51 case WM_NCMBUTTONDOWN:
52 case WM_NCMBUTTONUP:
53 /* case WM_NCMOUSEHOVER: */
54 /* case WM_NCMOUSELEAVE: */
55 case WM_NCMOUSEMOVE:
56 case WM_NCRBUTTONDBLCLK:
57 case WM_NCRBUTTONDOWN:
58 case WM_NCRBUTTONUP:
59 /* case WM_NCXBUTTONDBLCLK: */
60 /* case WM_NCXBUTTONDOWN: */
61 /* case WM_NCXBUTTONUP: */
62 case WM_RBUTTONDBLCLK:
63 case WM_RBUTTONDOWN:
64 case WM_RBUTTONUP:
65 /* case WM_XBUTTONDBLCLK: */
66 /* case WM_XBUTTONDOWN: */
67 /* case WM_XBUTTONUP: */
68 case WM_ACTIVATE:
69 case WM_CHAR:
70 case WM_DEADCHAR:
71 case WM_GETHOTKEY:
72 case WM_HOTKEY:
73 case WM_KEYDOWN:
74 case WM_KEYUP:
75 case WM_KILLFOCUS:
76 case WM_SETFOCUS:
77 case WM_SETHOTKEY:
78 case WM_SYSCHAR:
79 case WM_SYSDEADCHAR:
80 case WM_SYSKEYDOWN:
81 case WM_SYSKEYUP:
82
83 case WM_NCCALCSIZE:
84 return 0;
85
86 case WM_PAINT:
87 hdc = BeginPaint(hWnd, &ps);
88
89 WindowId = GetWindowLongPtrW(hWnd, GWLP_ID);
90
91 switch (WindowId)
92 {
93 case IDC_CPU_USAGE_GRAPH:
94 Graph_DrawCpuUsageGraph(hdc, hWnd);
95 break;
96 case IDC_MEM_USAGE_GRAPH:
97 Graph_DrawMemUsageGraph(hdc, hWnd);
98 break;
99 case IDC_MEM_USAGE_HISTORY_GRAPH:
100 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
101 break;
102 }
103
104 EndPaint(hWnd, &ps);
105 return 0;
106 }
107
108 /*
109 * Pass on all non-handled messages
110 */
111 return CallWindowProcW(OldGraphWndProc, hWnd, message, wParam, lParam);
112 }
113
Graph_DrawCpuUsageGraph(HDC hDC,HWND hWnd)114 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
115 {
116 RECT rcClient;
117 RECT rcBarLeft;
118 RECT rcBarRight;
119 RECT rcText;
120 COLORREF crPrevForeground;
121 WCHAR Text[260];
122 HFONT hOldFont;
123 ULONG CpuUsage;
124 ULONG CpuKernelUsage;
125 int nBars;
126 int nBarsUsed;
127 /* Bottom bars that are "used", i.e. are bright green, representing used cpu time */
128 int nBarsUsedKernel;
129 /* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */
130 int nBarsFree;
131 /* Top bars that are "unused", i.e. are dark green, representing free cpu time */
132 int i;
133
134 /*
135 * Get the client area rectangle
136 */
137 GetClientRect(hWnd, &rcClient);
138
139 /*
140 * Fill it with blackness
141 */
142 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
143
144 /*
145 * Get the CPU usage
146 */
147 CpuUsage = PerfDataGetProcessorUsage();
148
149 wsprintfW(Text, L"%d%%", (int)CpuUsage);
150
151 /*
152 * Draw the font text onto the graph
153 */
154 rcText = rcClient;
155 InflateRect(&rcText, -2, -2);
156 crPrevForeground = SetTextColor(hDC, RGB(0, 255, 0));
157 hOldFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
158 DrawTextW(hDC, Text, -1, &rcText, DT_BOTTOM | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE);
159 SelectObject(hDC, hOldFont);
160 SetTextColor(hDC, crPrevForeground);
161
162 /*
163 * Draw the graph. So first find out how many bars we can fit
164 */
165 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
166 nBarsUsed = (nBars * CpuUsage) / 100;
167 if ((CpuUsage) && (nBarsUsed == 0))
168 {
169 nBarsUsed = 1;
170 }
171 nBarsFree = nBars - (nlastBarsUsed>nBarsUsed ? nlastBarsUsed : nBarsUsed);
172
173 if (TaskManagerSettings.ShowKernelTimes)
174 {
175 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
176 nBarsUsedKernel = (nBars * CpuKernelUsage) / 100;
177 }
178 else
179 {
180 nBarsUsedKernel = 0;
181 }
182
183 /*
184 * Draw the bar graph
185 */
186 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
187 rcBarLeft.right = rcBarLeft.left + 16;
188 rcBarRight.left = rcBarLeft.left + 17;
189 rcBarRight.right = rcBarLeft.right + 17;
190 rcBarLeft.top = rcBarRight.top = 5;
191 rcBarLeft.bottom = rcBarRight.bottom = 7;
192
193 if (nBarsUsed < 0) nBarsUsed = 0;
194 if (nBarsUsed > nBars) nBarsUsed = nBars;
195
196 if (nBarsFree < 0) nBarsFree = 0;
197 if (nBarsFree > nBars) nBarsFree = nBars;
198
199 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0;
200 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;
201
202 /*
203 * Draw the "free" bars
204 */
205 for (i=0; i<nBarsFree; i++)
206 {
207 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
208 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
209
210 rcBarLeft.top += 3;
211 rcBarLeft.bottom += 3;
212
213 rcBarRight.top += 3;
214 rcBarRight.bottom += 3;
215 }
216
217 /*
218 * Draw the last "used" bars
219 */
220 if ((nlastBarsUsed - nBarsUsed) > 0) {
221 for (i=0; i< (nlastBarsUsed - nBarsUsed); i++)
222 {
223 if (nlastBarsUsed > 5000) nlastBarsUsed = 5000;
224
225 FillSolidRect(hDC, &rcBarLeft, MEDIUM_GREEN);
226 FillSolidRect(hDC, &rcBarRight, MEDIUM_GREEN);
227
228 rcBarLeft.top += 3;
229 rcBarLeft.bottom += 3;
230
231 rcBarRight.top += 3;
232 rcBarRight.bottom += 3;
233 }
234 }
235 nlastBarsUsed = nBarsUsed;
236 /*
237 * Draw the "used" bars
238 */
239 for (i=0; i<nBarsUsed; i++)
240 {
241 if (nBarsUsed > 5000) nBarsUsed = 5000;
242
243 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
244 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
245
246 rcBarLeft.top += 3;
247 rcBarLeft.bottom += 3;
248
249 rcBarRight.top += 3;
250 rcBarRight.bottom += 3;
251 }
252
253 /*
254 * Draw the "used" kernel bars
255 */
256
257 rcBarLeft.top -=3;
258 rcBarLeft.bottom -=3;
259
260 rcBarRight.top -=3;
261 rcBarRight.bottom -=3;
262
263 for (i=0; i<nBarsUsedKernel; i++)
264 {
265 FillSolidRect(hDC, &rcBarLeft, RED);
266 FillSolidRect(hDC, &rcBarRight, RED);
267
268 rcBarLeft.top -=3;
269 rcBarLeft.bottom -=3;
270
271 rcBarRight.top -=3;
272 rcBarRight.bottom -=3;
273 }
274
275 SelectObject(hDC, hOldFont);
276 }
277
Graph_DrawMemUsageGraph(HDC hDC,HWND hWnd)278 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
279 {
280 RECT rcClient;
281 RECT rcBarLeft;
282 RECT rcBarRight;
283 RECT rcText;
284 COLORREF crPrevForeground;
285 WCHAR Text[260];
286 HFONT hOldFont;
287 ULONGLONG CommitChargeTotal;
288 ULONGLONG CommitChargeLimit;
289 int nBars;
290 int nBarsUsed = 0;
291 /* Bottom bars that are "used", i.e. are bright green, representing used memory */
292 int nBarsFree;
293 /* Top bars that are "unused", i.e. are dark green, representing free memory */
294 int i;
295
296 /*
297 * Get the client area rectangle
298 */
299 GetClientRect(hWnd, &rcClient);
300
301 /*
302 * Fill it with blackness
303 */
304 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
305
306 /*
307 * Get the memory usage
308 */
309 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
310 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
311
312 if (CommitChargeTotal > 1024)
313 wsprintfW(Text, L"%d MB", (int)(CommitChargeTotal / 1024));
314 else
315 wsprintfW(Text, L"%d K", (int)CommitChargeTotal);
316 /*
317 * Draw the font text onto the graph
318 */
319 rcText = rcClient;
320 InflateRect(&rcText, -2, -2);
321 crPrevForeground = SetTextColor(hDC, RGB(0, 255, 0));
322 hOldFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
323 DrawTextW(hDC, Text, -1, &rcText, DT_BOTTOM | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE);
324 SelectObject(hDC, hOldFont);
325 SetTextColor(hDC, crPrevForeground);
326
327 /*
328 * Draw the graph. So first find out how many bars we can fit
329 */
330 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
331 if (CommitChargeLimit)
332 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
333 nBarsFree = nBars - nBarsUsed;
334
335 if (nBarsUsed < 0) nBarsUsed = 0;
336 if (nBarsUsed > nBars) nBarsUsed = nBars;
337
338 if (nBarsFree < 0) nBarsFree = 0;
339 if (nBarsFree > nBars) nBarsFree = nBars;
340
341 /*
342 * Draw the bar graph
343 */
344 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
345 rcBarLeft.right = rcBarLeft.left + 16;
346 rcBarRight.left = rcBarLeft.left + 17;
347 rcBarRight.right = rcBarLeft.right + 17;
348 rcBarLeft.top = rcBarRight.top = 5;
349 rcBarLeft.bottom = rcBarRight.bottom = 7;
350
351 /*
352 * Draw the "free" bars
353 */
354 for (i=0; i<nBarsFree; i++)
355 {
356 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
357 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
358
359 rcBarLeft.top += 3;
360 rcBarLeft.bottom += 3;
361
362 rcBarRight.top += 3;
363 rcBarRight.bottom += 3;
364 }
365
366 /*
367 * Draw the "used" bars
368 */
369 for (i=0; i<nBarsUsed; i++)
370 {
371 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
372 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
373
374 rcBarLeft.top += 3;
375 rcBarLeft.bottom += 3;
376
377 rcBarRight.top += 3;
378 rcBarRight.bottom += 3;
379 }
380
381 SelectObject(hDC, hOldFont);
382 }
383
Graph_DrawMemUsageHistoryGraph(HDC hDC,HWND hWnd)384 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
385 {
386 RECT rcClient;
387 //ULONGLONG CommitChargeLimit;
388 int i;
389 static int offset = 0;
390
391 if (offset++ >= 10)
392 offset = 0;
393
394 /*
395 * Get the client area rectangle
396 */
397 GetClientRect(hWnd, &rcClient);
398
399 /*
400 * Fill it with blackness
401 */
402 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
403
404 /*
405 * Get the memory usage
406 */
407 //CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
408
409 /*
410 * Draw the graph background and horizontal bars
411 */
412 for (i=0; i<rcClient.bottom; i++)
413 {
414 if ((i % 11) == 0)
415 {
416 //FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN);
417 }
418 }
419
420 /*
421 * Draw the vertical bars
422 */
423 for (i=11; i<rcClient.right + offset; i++)
424 {
425 if ((i % 11) == 0)
426 {
427 //FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN);
428 }
429 }
430
431 /*
432 * Draw the memory usage
433 */
434 for (i=rcClient.right; i>=0; i--)
435 {
436 }
437 }
438