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 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 88 hdc = BeginPaint(hWnd, &ps); 89 90 WindowId = GetWindowLongPtrW(hWnd, GWLP_ID); 91 92 switch (WindowId) 93 { 94 case IDC_CPU_USAGE_GRAPH: 95 Graph_DrawCpuUsageGraph(hdc, hWnd); 96 break; 97 case IDC_MEM_USAGE_GRAPH: 98 Graph_DrawMemUsageGraph(hdc, hWnd); 99 break; 100 case IDC_MEM_USAGE_HISTORY_GRAPH: 101 Graph_DrawMemUsageHistoryGraph(hdc, hWnd); 102 break; 103 } 104 105 EndPaint(hWnd, &ps); 106 107 return 0; 108 109 } 110 111 /* 112 * We pass on all non-handled messages 113 */ 114 return CallWindowProcW(OldGraphWndProc, hWnd, message, wParam, lParam); 115 } 116 117 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd) 118 { 119 RECT rcClient; 120 RECT rcBarLeft; 121 RECT rcBarRight; 122 RECT rcText; 123 COLORREF crPrevForeground; 124 WCHAR Text[260]; 125 HFONT hOldFont; 126 ULONG CpuUsage; 127 ULONG CpuKernelUsage; 128 int nBars; 129 int nBarsUsed; 130 /* Bottom bars that are "used", i.e. are bright green, representing used cpu time */ 131 int nBarsUsedKernel; 132 /* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */ 133 int nBarsFree; 134 /* Top bars that are "unused", i.e. are dark green, representing free cpu time */ 135 int i; 136 137 /* 138 * Get the client area rectangle 139 */ 140 GetClientRect(hWnd, &rcClient); 141 142 /* 143 * Fill it with blackness 144 */ 145 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0)); 146 147 /* 148 * Get the CPU usage 149 */ 150 CpuUsage = PerfDataGetProcessorUsage(); 151 152 wsprintfW(Text, L"%d%%", (int)CpuUsage); 153 154 /* 155 * Draw the font text onto the graph 156 */ 157 rcText = rcClient; 158 InflateRect(&rcText, -2, -2); 159 crPrevForeground = SetTextColor(hDC, RGB(0, 255, 0)); 160 hOldFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT)); 161 DrawTextW(hDC, Text, -1, &rcText, DT_BOTTOM | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE); 162 SelectObject(hDC, hOldFont); 163 SetTextColor(hDC, crPrevForeground); 164 165 /* 166 * Now we have to draw the graph 167 * So first find out how many bars we can fit 168 */ 169 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3; 170 nBarsUsed = (nBars * CpuUsage) / 100; 171 if ((CpuUsage) && (nBarsUsed == 0)) 172 { 173 nBarsUsed = 1; 174 } 175 nBarsFree = nBars - (nlastBarsUsed>nBarsUsed ? nlastBarsUsed : nBarsUsed); 176 177 if (TaskManagerSettings.ShowKernelTimes) 178 { 179 CpuKernelUsage = PerfDataGetProcessorSystemUsage(); 180 nBarsUsedKernel = (nBars * CpuKernelUsage) / 100; 181 } 182 else 183 { 184 nBarsUsedKernel = 0; 185 } 186 187 /* 188 * Now draw the bar graph 189 */ 190 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2; 191 rcBarLeft.right = rcBarLeft.left + 16; 192 rcBarRight.left = rcBarLeft.left + 17; 193 rcBarRight.right = rcBarLeft.right + 17; 194 rcBarLeft.top = rcBarRight.top = 5; 195 rcBarLeft.bottom = rcBarRight.bottom = 7; 196 197 if (nBarsUsed < 0) nBarsUsed = 0; 198 if (nBarsUsed > nBars) nBarsUsed = nBars; 199 200 if (nBarsFree < 0) nBarsFree = 0; 201 if (nBarsFree > nBars) nBarsFree = nBars; 202 203 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0; 204 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars; 205 206 /* 207 * Draw the "free" bars 208 */ 209 for (i=0; i<nBarsFree; i++) 210 { 211 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN); 212 FillSolidRect(hDC, &rcBarRight, DARK_GREEN); 213 214 rcBarLeft.top += 3; 215 rcBarLeft.bottom += 3; 216 217 rcBarRight.top += 3; 218 rcBarRight.bottom += 3; 219 } 220 221 /* 222 * Draw the last "used" bars 223 */ 224 if ((nlastBarsUsed - nBarsUsed) > 0) { 225 for (i=0; i< (nlastBarsUsed - nBarsUsed); i++) 226 { 227 if (nlastBarsUsed > 5000) nlastBarsUsed = 5000; 228 229 FillSolidRect(hDC, &rcBarLeft, MEDIUM_GREEN); 230 FillSolidRect(hDC, &rcBarRight, MEDIUM_GREEN); 231 232 rcBarLeft.top += 3; 233 rcBarLeft.bottom += 3; 234 235 rcBarRight.top += 3; 236 rcBarRight.bottom += 3; 237 } 238 } 239 nlastBarsUsed = nBarsUsed; 240 /* 241 * Draw the "used" bars 242 */ 243 for (i=0; i<nBarsUsed; i++) 244 { 245 if (nBarsUsed > 5000) nBarsUsed = 5000; 246 247 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN); 248 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN); 249 250 rcBarLeft.top += 3; 251 rcBarLeft.bottom += 3; 252 253 rcBarRight.top += 3; 254 rcBarRight.bottom += 3; 255 } 256 257 /* 258 * Draw the "used" kernel bars 259 */ 260 261 rcBarLeft.top -=3; 262 rcBarLeft.bottom -=3; 263 264 rcBarRight.top -=3; 265 rcBarRight.bottom -=3; 266 267 for (i=0; i<nBarsUsedKernel; i++) 268 { 269 270 FillSolidRect(hDC, &rcBarLeft, RED); 271 FillSolidRect(hDC, &rcBarRight, RED); 272 273 rcBarLeft.top -=3; 274 rcBarLeft.bottom -=3; 275 276 rcBarRight.top -=3; 277 rcBarRight.bottom -=3; 278 279 } 280 281 SelectObject(hDC, hOldFont); 282 } 283 284 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd) 285 { 286 RECT rcClient; 287 RECT rcBarLeft; 288 RECT rcBarRight; 289 RECT rcText; 290 COLORREF crPrevForeground; 291 WCHAR Text[260]; 292 HFONT hOldFont; 293 ULONGLONG CommitChargeTotal; 294 ULONGLONG CommitChargeLimit; 295 int nBars; 296 int nBarsUsed = 0; 297 /* Bottom bars that are "used", i.e. are bright green, representing used memory */ 298 int nBarsFree; 299 /* Top bars that are "unused", i.e. are dark green, representing free memory */ 300 int i; 301 302 /* 303 * Get the client area rectangle 304 */ 305 GetClientRect(hWnd, &rcClient); 306 307 /* 308 * Fill it with blackness 309 */ 310 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0)); 311 312 /* 313 * Get the memory usage 314 */ 315 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK(); 316 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK(); 317 318 if (CommitChargeTotal > 1024) 319 wsprintfW(Text, L"%d MB", (int)(CommitChargeTotal / 1024)); 320 else 321 wsprintfW(Text, L"%d K", (int)CommitChargeTotal); 322 /* 323 * Draw the font text onto the graph 324 */ 325 rcText = rcClient; 326 InflateRect(&rcText, -2, -2); 327 crPrevForeground = SetTextColor(hDC, RGB(0, 255, 0)); 328 hOldFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT)); 329 DrawTextW(hDC, Text, -1, &rcText, DT_BOTTOM | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE); 330 SelectObject(hDC, hOldFont); 331 SetTextColor(hDC, crPrevForeground); 332 333 /* 334 * Now we have to draw the graph 335 * So first find out how many bars we can fit 336 */ 337 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3; 338 if (CommitChargeLimit) 339 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100; 340 nBarsFree = nBars - nBarsUsed; 341 342 if (nBarsUsed < 0) nBarsUsed = 0; 343 if (nBarsUsed > nBars) nBarsUsed = nBars; 344 345 if (nBarsFree < 0) nBarsFree = 0; 346 if (nBarsFree > nBars) nBarsFree = nBars; 347 348 /* 349 * Now draw the bar graph 350 */ 351 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2; 352 rcBarLeft.right = rcBarLeft.left + 16; 353 rcBarRight.left = rcBarLeft.left + 17; 354 rcBarRight.right = rcBarLeft.right + 17; 355 rcBarLeft.top = rcBarRight.top = 5; 356 rcBarLeft.bottom = rcBarRight.bottom = 7; 357 358 /* 359 * Draw the "free" bars 360 */ 361 for (i=0; i<nBarsFree; i++) 362 { 363 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN); 364 FillSolidRect(hDC, &rcBarRight, DARK_GREEN); 365 366 rcBarLeft.top += 3; 367 rcBarLeft.bottom += 3; 368 369 rcBarRight.top += 3; 370 rcBarRight.bottom += 3; 371 } 372 373 /* 374 * Draw the "used" bars 375 */ 376 for (i=0; i<nBarsUsed; i++) 377 { 378 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN); 379 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN); 380 381 rcBarLeft.top += 3; 382 rcBarLeft.bottom += 3; 383 384 rcBarRight.top += 3; 385 rcBarRight.bottom += 3; 386 } 387 388 SelectObject(hDC, hOldFont); 389 } 390 391 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd) 392 { 393 RECT rcClient; 394 //ULONGLONG CommitChargeLimit; 395 int i; 396 static int offset = 0; 397 398 if (offset++ >= 10) 399 offset = 0; 400 401 /* 402 * Get the client area rectangle 403 */ 404 GetClientRect(hWnd, &rcClient); 405 406 /* 407 * Fill it with blackness 408 */ 409 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0)); 410 411 /* 412 * Get the memory usage 413 */ 414 //CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK(); 415 416 /* 417 * Draw the graph background 418 * 419 * Draw the horizontal bars 420 */ 421 for (i=0; i<rcClient.bottom; i++) 422 { 423 if ((i % 11) == 0) 424 { 425 /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN); */ 426 } 427 } 428 /* 429 * Draw the vertical bars 430 */ 431 for (i=11; i<rcClient.right + offset; i++) 432 { 433 if ((i % 11) == 0) 434 { 435 /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN); */ 436 } 437 } 438 439 /* 440 * Draw the memory usage 441 */ 442 for (i=rcClient.right; i>=0; i--) 443 { 444 } 445 } 446