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 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 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 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 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