Fixes to performance page resizing and font.bmp updated.
[reactos.git] / rosapps / taskmgr / GraphCtrl.cpp
1 /*
2 * ReactOS Task Manager
3 *
4 * GraphCtrl.cpp
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "stdafx.h"
24 #include "math.h"
25 #include "GraphCtrl.h"
26 #include "TaskMgr.h"
27
28 #ifdef _DEBUG
29 #define new DEBUG_NEW
30 #undef THIS_FILE
31 static char THIS_FILE[] = __FILE__;
32 #endif
33
34
35 LONG OldGraphCtrlWndProc;
36
37
38 TGraphCtrl::TGraphCtrl() :
39 m_hWnd(0),
40 m_hParentWnd(0),
41 m_dcGrid(0),
42 m_dcPlot(0),
43 m_bitmapOldGrid(0),
44 m_bitmapOldPlot(0),
45 m_bitmapGrid(0),
46 m_bitmapPlot(0),
47 m_brushBack(0)
48 {
49 //RECT m_rectClient;
50 //RECT m_rectPlot;
51 m_penPlot[0] = 0;
52 m_penPlot[1] = 0;
53 m_penPlot[2] = 0;
54 m_penPlot[3] = 0;
55
56 // since plotting is based on a LineTo for each new point
57 // we need a starting point (i.e. a "previous" point)
58 // use 0.0 as the default first point.
59 // these are public member variables, and can be changed outside
60 // (after construction). Therefore m_perviousPosition could be set to
61 // a more appropriate value prior to the first call to SetPosition.
62 m_dPreviousPosition[0] = 0.0;
63 m_dPreviousPosition[1] = 0.0;
64 m_dPreviousPosition[2] = 0.0;
65 m_dPreviousPosition[3] = 0.0;
66
67 // public variable for the number of decimal places on the y axis
68 m_nYDecimals = 3;
69
70 // set some initial values for the scaling until "SetRange" is called.
71 // these are protected varaibles and must be set with SetRange
72 // in order to ensure that m_dRange is updated accordingly
73 // m_dLowerLimit = -10.0;
74 // m_dUpperLimit = 10.0;
75 m_dLowerLimit = 0.0;
76 m_dUpperLimit = 100.0;
77 m_dRange = m_dUpperLimit - m_dLowerLimit; // protected member variable
78
79 // m_nShiftPixels determines how much the plot shifts (in terms of pixels)
80 // with the addition of a new data point
81 m_nShiftPixels = 4;
82 m_nHalfShiftPixels = m_nShiftPixels/2; // protected
83 m_nPlotShiftPixels = m_nShiftPixels + m_nHalfShiftPixels; // protected
84
85 // background, grid and data colors
86 // these are public variables and can be set directly
87 m_crBackColor = RGB( 0, 0, 0); // see also SetBackgroundColor
88 m_crGridColor = RGB( 0, 255, 255); // see also SetGridColor
89 m_crPlotColor[0] = RGB(255, 255, 255); // see also SetPlotColor
90 m_crPlotColor[1] = RGB(100, 255, 255); // see also SetPlotColor
91 m_crPlotColor[2] = RGB(255, 100, 255); // see also SetPlotColor
92 m_crPlotColor[3] = RGB(255, 255, 100); // see also SetPlotColor
93
94 // protected variables
95 int i;
96 for (i = 0; i < MAX_PLOTS; i++) {
97 m_penPlot[i] = CreatePen(PS_SOLID, 0, m_crPlotColor[i]);
98 }
99 m_brushBack = CreateSolidBrush(m_crBackColor);
100
101 // public member variables, can be set directly
102 strcpy(m_strXUnitsString, "Samples"); // can also be set with SetXUnits
103 strcpy(m_strYUnitsString, "Y units"); // can also be set with SetYUnits
104
105 // protected bitmaps to restore the memory DC's
106 m_bitmapOldGrid = NULL;
107 m_bitmapOldPlot = NULL;
108 #if 0
109 for (i = 0; i < MAX_CTRLS; i++) {
110 if (pCtrlArray[i] == 0) {
111 pCtrlArray[i] = this;
112 }
113 }
114 #endif
115 }
116
117 /////////////////////////////////////////////////////////////////////////////
118 TGraphCtrl::~TGraphCtrl()
119 {
120 // just to be picky restore the bitmaps for the two memory dc's
121 // (these dc's are being destroyed so there shouldn't be any leaks)
122 if (m_bitmapOldGrid != NULL) SelectObject(m_dcGrid, m_bitmapOldGrid);
123 if (m_bitmapOldPlot != NULL) SelectObject(m_dcPlot, m_bitmapOldPlot);
124 if (m_bitmapGrid != NULL) DeleteObject(m_bitmapGrid);
125 if (m_bitmapPlot != NULL) DeleteObject(m_bitmapPlot);
126 if (m_dcGrid != NULL) DeleteDC(m_dcGrid);
127 if (m_dcPlot != NULL) DeleteDC(m_dcPlot);
128 if (m_brushBack != NULL) DeleteObject(m_brushBack);
129 #if 0
130 for (int i = 0; i < MAX_CTRLS; i++) {
131 if (pCtrlArray[i] == this) {
132 pCtrlArray[i] = 0;
133 }
134 }
135 #endif
136 }
137
138 /////////////////////////////////////////////////////////////////////////////
139 BOOL TGraphCtrl::Create(HWND hWnd, HWND hParentWnd, UINT nID)
140 {
141 BOOL result = 0;
142
143 m_hParentWnd = hParentWnd;
144 m_hWnd = hWnd;
145 Resize();
146 if (result != 0)
147 InvalidateCtrl();
148 return result;
149 }
150
151 /*
152 BOOL TGraphCtrl::Create(DWORD dwStyle, const RECT& rect,
153 HWND hParentWnd, UINT nID)
154 {
155 BOOL result = 0;
156
157 m_hParentWnd = hParentWnd;
158 // GetClientRect(m_hParentWnd, &m_rectClient);
159
160 // set some member variables to avoid multiple function calls
161 m_nClientHeight = rect.bottom - rect.top;//rect.Height();
162 m_nClientWidth = rect.right - rect.left;//rect.Width();
163 // m_nClientHeight = cx;
164 // m_nClientWidth = cy;
165
166 // the "left" coordinate and "width" will be modified in
167 // InvalidateCtrl to be based on the width of the y axis scaling
168 #if 0
169 m_rectPlot.left = 20;
170 m_rectPlot.top = 10;
171 m_rectPlot.right = rect.right-10;
172 m_rectPlot.bottom = rect.bottom-25;
173 #else
174 m_rectPlot.left = -1;
175 m_rectPlot.top = -1;
176 m_rectPlot.right = rect.right-0;
177 m_rectPlot.bottom = rect.bottom-0;
178 #endif
179 // set some member variables to avoid multiple function calls
180 m_nPlotHeight = m_rectPlot.bottom - m_rectPlot.top;//m_rectPlot.Height();
181 m_nPlotWidth = m_rectPlot.right - m_rectPlot.left;//m_rectPlot.Width();
182
183 // set the scaling factor for now, this can be adjusted
184 // in the SetRange functions
185 m_dVerticalFactor = (double)m_nPlotHeight / m_dRange;
186
187 if (result != 0)
188 InvalidateCtrl();
189 return result;
190 }
191 */
192 /////////////////////////////////////////////////////////////////////////////
193 void TGraphCtrl::SetRange(double dLower, double dUpper, int nDecimalPlaces)
194 {
195 //ASSERT(dUpper > dLower);
196 m_dLowerLimit = dLower;
197 m_dUpperLimit = dUpper;
198 m_nYDecimals = nDecimalPlaces;
199 m_dRange = m_dUpperLimit - m_dLowerLimit;
200 m_dVerticalFactor = (double)m_nPlotHeight / m_dRange;
201 // clear out the existing garbage, re-start with a clean plot
202 InvalidateCtrl();
203 }
204
205
206 /////////////////////////////////////////////////////////////////////////////
207 void TGraphCtrl::SetXUnits(const char* string)
208 {
209 strncpy(m_strXUnitsString, string, sizeof(m_strXUnitsString) - 1);
210 // clear out the existing garbage, re-start with a clean plot
211 InvalidateCtrl();
212 }
213
214 /////////////////////////////////////////////////////////////////////////////
215 void TGraphCtrl::SetYUnits(const char* string)
216 {
217 strncpy(m_strYUnitsString, string, sizeof(m_strYUnitsString) - 1);
218 // clear out the existing garbage, re-start with a clean plot
219 InvalidateCtrl();
220 }
221
222 /////////////////////////////////////////////////////////////////////////////
223 void TGraphCtrl::SetGridColor(COLORREF color)
224 {
225 m_crGridColor = color;
226 // clear out the existing garbage, re-start with a clean plot
227 InvalidateCtrl();
228 }
229
230 /////////////////////////////////////////////////////////////////////////////
231 void TGraphCtrl::SetPlotColor(int plot, COLORREF color)
232 {
233 m_crPlotColor[plot] = color;
234 DeleteObject(m_penPlot[plot]);
235 m_penPlot[plot] = CreatePen(PS_SOLID, 0, m_crPlotColor[plot]);
236 // clear out the existing garbage, re-start with a clean plot
237 InvalidateCtrl();
238 }
239
240 /////////////////////////////////////////////////////////////////////////////
241 void TGraphCtrl::SetBackgroundColor(COLORREF color)
242 {
243 m_crBackColor = color;
244 DeleteObject(m_brushBack);
245 m_brushBack = CreateSolidBrush(m_crBackColor);
246 // clear out the existing garbage, re-start with a clean plot
247 InvalidateCtrl();
248
249 }
250
251 /////////////////////////////////////////////////////////////////////////////
252 void TGraphCtrl::InvalidateCtrl()
253 {
254 // There is a lot of drawing going on here - particularly in terms of
255 // drawing the grid. Don't panic, this is all being drawn (only once)
256 // to a bitmap. The result is then BitBlt'd to the control whenever needed.
257 int i, j;
258 int nCharacters;
259 int nTopGridPix, nMidGridPix, nBottomGridPix;
260
261 HPEN oldPen;
262 HPEN solidPen = CreatePen(PS_SOLID, 0, m_crGridColor);
263 //HFONT axisFont, yUnitFont, oldFont;
264 //char strTemp[50];
265
266 // in case we haven't established the memory dc's
267 //CClientDC dc(this);
268 HDC dc = GetDC(m_hParentWnd);
269
270 // if we don't have one yet, set up a memory dc for the grid
271 if (m_dcGrid == NULL) {
272 m_dcGrid = CreateCompatibleDC(dc);
273 m_bitmapGrid = CreateCompatibleBitmap(dc, m_nClientWidth, m_nClientHeight);
274 m_bitmapOldGrid = (HBITMAP)SelectObject(m_dcGrid, m_bitmapGrid);
275 }
276
277 SetBkColor(m_dcGrid, m_crBackColor);
278
279 // fill the grid background
280 FillRect(m_dcGrid, &m_rectClient, m_brushBack);
281
282 // draw the plot rectangle:
283 // determine how wide the y axis scaling values are
284 nCharacters = abs((int)log10(fabs(m_dUpperLimit)));
285 nCharacters = max(nCharacters, abs((int)log10(fabs(m_dLowerLimit))));
286
287 // add the units digit, decimal point and a minus sign, and an extra space
288 // as well as the number of decimal places to display
289 nCharacters = nCharacters + 4 + m_nYDecimals;
290
291 // adjust the plot rectangle dimensions
292 // assume 6 pixels per character (this may need to be adjusted)
293 // m_rectPlot.left = m_rectClient.left + 6*(nCharacters);
294 m_rectPlot.left = m_rectClient.left;
295 m_nPlotWidth = m_rectPlot.right - m_rectPlot.left;//m_rectPlot.Width();
296
297 // draw the plot rectangle
298 oldPen = (HPEN)SelectObject(m_dcGrid, solidPen);
299 MoveToEx(m_dcGrid, m_rectPlot.left, m_rectPlot.top, NULL);
300 LineTo(m_dcGrid, m_rectPlot.right+1, m_rectPlot.top);
301 LineTo(m_dcGrid, m_rectPlot.right+1, m_rectPlot.bottom+1);
302 LineTo(m_dcGrid, m_rectPlot.left, m_rectPlot.bottom+1);
303 // LineTo(m_dcGrid, m_rectPlot.left, m_rectPlot.top);
304 SelectObject(m_dcGrid, oldPen);
305 DeleteObject(solidPen);
306
307 // draw the dotted lines,
308 // use SetPixel instead of a dotted pen - this allows for a
309 // finer dotted line and a more "technical" look
310 nMidGridPix = (m_rectPlot.top + m_rectPlot.bottom)/2;
311 nTopGridPix = nMidGridPix - m_nPlotHeight/4;
312 nBottomGridPix = nMidGridPix + m_nPlotHeight/4;
313
314 for (i=m_rectPlot.left; i<m_rectPlot.right; i+=2) {
315 SetPixel(m_dcGrid, i, nTopGridPix, m_crGridColor);
316 SetPixel(m_dcGrid, i, nMidGridPix, m_crGridColor);
317 SetPixel(m_dcGrid, i, nBottomGridPix, m_crGridColor);
318 }
319
320 for (i=m_rectPlot.left; i<m_rectPlot.right; i+=10) {
321 for (j=m_rectPlot.top; j<m_rectPlot.bottom; j+=2) {
322 SetPixel(m_dcGrid, i, j, m_crGridColor);
323 // SetPixel(m_dcGrid, i, j, m_crGridColor);
324 // SetPixel(m_dcGrid, i, j, m_crGridColor);
325 }
326 }
327
328 #if 0
329 // create some fonts (horizontal and vertical)
330 // use a height of 14 pixels and 300 weight
331 // (these may need to be adjusted depending on the display)
332 axisFont = CreateFont (14, 0, 0, 0, 300,
333 FALSE, FALSE, 0, ANSI_CHARSET,
334 OUT_DEFAULT_PRECIS,
335 CLIP_DEFAULT_PRECIS,
336 DEFAULT_QUALITY,
337 DEFAULT_PITCH|FF_SWISS, "Arial");
338 yUnitFont = CreateFont (14, 0, 900, 0, 300,
339 FALSE, FALSE, 0, ANSI_CHARSET,
340 OUT_DEFAULT_PRECIS,
341 CLIP_DEFAULT_PRECIS,
342 DEFAULT_QUALITY,
343 DEFAULT_PITCH|FF_SWISS, "Arial");
344
345 // grab the horizontal font
346 oldFont = (HFONT)SelectObject(m_dcGrid, axisFont);
347
348 // y max
349 SetTextColor(m_dcGrid, m_crGridColor);
350 SetTextAlign(m_dcGrid, TA_RIGHT|TA_TOP);
351 sprintf(strTemp, "%.*lf", m_nYDecimals, m_dUpperLimit);
352 TextOut(m_dcGrid, m_rectPlot.left-4, m_rectPlot.top, strTemp, strlen(strTemp));
353
354 // y min
355 SetTextAlign(m_dcGrid, TA_RIGHT|TA_BASELINE);
356 sprintf(strTemp, "%.*lf", m_nYDecimals, m_dLowerLimit);
357 TextOut(m_dcGrid, m_rectPlot.left-4, m_rectPlot.bottom, strTemp, strlen(strTemp));
358
359 // x min
360 SetTextAlign(m_dcGrid, TA_LEFT|TA_TOP);
361 TextOut(m_dcGrid, m_rectPlot.left, m_rectPlot.bottom+4, "0", 1);
362
363 // x max
364 SetTextAlign(m_dcGrid, TA_RIGHT|TA_TOP);
365 sprintf(strTemp, "%d", m_nPlotWidth/m_nShiftPixels);
366 TextOut(m_dcGrid, m_rectPlot.right, m_rectPlot.bottom+4, strTemp, strlen(strTemp));
367
368 // x units
369 SetTextAlign(m_dcGrid, TA_CENTER|TA_TOP);
370 TextOut(m_dcGrid, (m_rectPlot.left+m_rectPlot.right)/2,
371 m_rectPlot.bottom+4, m_strXUnitsString, strlen(m_strXUnitsString));
372
373 // restore the font
374 SelectObject(m_dcGrid, oldFont);
375
376 // y units
377 oldFont = (HFONT)SelectObject(m_dcGrid, yUnitFont);
378 SetTextAlign(m_dcGrid, TA_CENTER|TA_BASELINE);
379 TextOut(m_dcGrid, (m_rectClient.left+m_rectPlot.left)/2,
380 (m_rectPlot.bottom+m_rectPlot.top)/2, m_strYUnitsString, strlen(m_strYUnitsString));
381 SelectObject(m_dcGrid, oldFont);
382 #endif
383 // at this point we are done filling the the grid bitmap,
384 // no more drawing to this bitmap is needed until the setting are changed
385
386 // if we don't have one yet, set up a memory dc for the plot
387 if (m_dcPlot == NULL) {
388 m_dcPlot = CreateCompatibleDC(dc);
389 m_bitmapPlot = CreateCompatibleBitmap(dc, m_nClientWidth, m_nClientHeight);
390 m_bitmapOldPlot = (HBITMAP)SelectObject(m_dcPlot, m_bitmapPlot);
391 }
392
393 // make sure the plot bitmap is cleared
394 SetBkColor(m_dcPlot, m_crBackColor);
395 FillRect(m_dcPlot, &m_rectClient, m_brushBack);
396
397 // finally, force the plot area to redraw
398 InvalidateRect(m_hParentWnd, &m_rectClient, TRUE);
399 ReleaseDC(m_hParentWnd, dc);
400
401 }
402
403 /////////////////////////////////////////////////////////////////////////////
404 double TGraphCtrl::AppendPoint(double dNewPoint0, double dNewPoint1,
405 double dNewPoint2, double dNewPoint3)
406 {
407 // append a data point to the plot & return the previous point
408 double dPrevious;
409
410 dPrevious = m_dCurrentPosition[0];
411 m_dCurrentPosition[0] = dNewPoint0;
412 m_dCurrentPosition[1] = dNewPoint1;
413 m_dCurrentPosition[2] = dNewPoint2;
414 m_dCurrentPosition[3] = dNewPoint3;
415 DrawPoint();
416 //Invalidate();
417 return dPrevious;
418
419 }
420
421 ////////////////////////////////////////////////////////////////////////////
422 void TGraphCtrl::Paint(HWND hWnd, HDC dc)
423 {
424 HDC memDC;
425 HBITMAP memBitmap;
426 HBITMAP oldBitmap; // bitmap originally found in CMemDC
427
428 // RECT rcClient;
429 // GetClientRect(hWnd, &rcClient);
430 // FillSolidRect(dc, &rcClient, RGB(255, 0, 255));
431 // m_nClientWidth = rcClient.right - rcClient.left;
432 // m_nClientHeight = rcClient.bottom - rcClient.top;
433
434 // no real plotting work is performed here,
435 // just putting the existing bitmaps on the client
436
437 // to avoid flicker, establish a memory dc, draw to it
438 // and then BitBlt it to the client
439 memDC = CreateCompatibleDC(dc);
440 memBitmap = (HBITMAP)CreateCompatibleBitmap(dc, m_nClientWidth, m_nClientHeight);
441 oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
442
443 if (memDC != NULL) {
444 // first drop the grid on the memory dc
445 BitBlt(memDC, 0, 0, m_nClientWidth, m_nClientHeight, m_dcGrid, 0, 0, SRCCOPY);
446 // now add the plot on top as a "pattern" via SRCPAINT.
447 // works well with dark background and a light plot
448 BitBlt(memDC, 0, 0, m_nClientWidth, m_nClientHeight, m_dcPlot, 0, 0, SRCPAINT); //SRCPAINT
449 // finally send the result to the display
450 BitBlt(dc, 0, 0, m_nClientWidth, m_nClientHeight, memDC, 0, 0, SRCCOPY);
451 }
452 SelectObject(memDC, oldBitmap);
453 DeleteObject(memBitmap);
454 DeleteDC(memDC);
455 }
456
457 /////////////////////////////////////////////////////////////////////////////
458 void TGraphCtrl::DrawPoint()
459 {
460 // this does the work of "scrolling" the plot to the left
461 // and appending a new data point all of the plotting is
462 // directed to the memory based bitmap associated with m_dcPlot
463 // the will subsequently be BitBlt'd to the client in Paint
464
465 int currX, prevX, currY, prevY;
466 HPEN oldPen;
467 RECT rectCleanUp;
468
469 if (m_dcPlot != NULL) {
470 // shift the plot by BitBlt'ing it to itself
471 // note: the m_dcPlot covers the entire client
472 // but we only shift bitmap that is the size
473 // of the plot rectangle
474 // grab the right side of the plot (exluding m_nShiftPixels on the left)
475 // move this grabbed bitmap to the left by m_nShiftPixels
476
477 BitBlt(m_dcPlot, m_rectPlot.left, m_rectPlot.top+1,
478 m_nPlotWidth, m_nPlotHeight, m_dcPlot,
479 m_rectPlot.left+m_nShiftPixels, m_rectPlot.top+1,
480 SRCCOPY);
481
482 // establish a rectangle over the right side of plot
483 // which now needs to be cleaned up proir to adding the new point
484 rectCleanUp = m_rectPlot;
485 rectCleanUp.left = rectCleanUp.right - m_nShiftPixels;
486
487 // fill the cleanup area with the background
488 FillRect(m_dcPlot, &rectCleanUp, m_brushBack);
489
490 // draw the next line segement
491 for (int i = 0; i < MAX_PLOTS; i++) {
492
493 // grab the plotting pen
494 oldPen = (HPEN)SelectObject(m_dcPlot, m_penPlot[i]);
495
496 // move to the previous point
497 prevX = m_rectPlot.right-m_nPlotShiftPixels;
498 prevY = m_rectPlot.bottom -
499 (long)((m_dPreviousPosition[i] - m_dLowerLimit) * m_dVerticalFactor);
500 MoveToEx(m_dcPlot, prevX, prevY, NULL);
501
502 // draw to the current point
503 currX = m_rectPlot.right-m_nHalfShiftPixels;
504 currY = m_rectPlot.bottom -
505 (long)((m_dCurrentPosition[i] - m_dLowerLimit) * m_dVerticalFactor);
506 LineTo(m_dcPlot, currX, currY);
507
508 // restore the pen
509 SelectObject(m_dcPlot, oldPen);
510
511 // if the data leaks over the upper or lower plot boundaries
512 // fill the upper and lower leakage with the background
513 // this will facilitate clipping on an as needed basis
514 // as opposed to always calling IntersectClipRect
515
516 if ((prevY <= m_rectPlot.top) || (currY <= m_rectPlot.top)) {
517 RECT rc;
518 rc.bottom = m_rectPlot.top+1;
519 rc.left = prevX;
520 rc.right = currX+1;
521 rc.top = m_rectClient.top;
522 FillRect(m_dcPlot, &rc, m_brushBack);
523 }
524 if ((prevY >= m_rectPlot.bottom) || (currY >= m_rectPlot.bottom)) {
525 RECT rc;
526 rc.bottom = m_rectClient.bottom+1;
527 rc.left = prevX;
528 rc.right = currX+1;
529 rc.top = m_rectPlot.bottom+1;
530 //RECT rc(prevX, m_rectPlot.bottom+1, currX+1, m_rectClient.bottom+1);
531 FillRect(m_dcPlot, &rc, m_brushBack);
532 }
533
534 // store the current point for connection to the next point
535 m_dPreviousPosition[i] = m_dCurrentPosition[i];
536 }
537 }
538 }
539
540 /////////////////////////////////////////////////////////////////////////////
541 void TGraphCtrl::Resize(void)
542 {
543 // NOTE: Resize automatically gets called during the setup of the control
544 GetClientRect(m_hWnd, &m_rectClient);
545
546 // set some member variables to avoid multiple function calls
547 m_nClientHeight = m_rectClient.bottom - m_rectClient.top;//m_rectClient.Height();
548 m_nClientWidth = m_rectClient.right - m_rectClient.left;//m_rectClient.Width();
549
550 // the "left" coordinate and "width" will be modified in
551 // InvalidateCtrl to be based on the width of the y axis scaling
552 #if 0
553 m_rectPlot.left = 20;
554 m_rectPlot.top = 10;
555 m_rectPlot.right = m_rectClient.right-10;
556 m_rectPlot.bottom = m_rectClient.bottom-25;
557 #else
558 m_rectPlot.left = 0;
559 m_rectPlot.top = -1;
560 m_rectPlot.right = m_rectClient.right-0;
561 m_rectPlot.bottom = m_rectClient.bottom-0;
562 #endif
563
564 // set some member variables to avoid multiple function calls
565 m_nPlotHeight = m_rectPlot.bottom - m_rectPlot.top;//m_rectPlot.Height();
566 m_nPlotWidth = m_rectPlot.right - m_rectPlot.left;//m_rectPlot.Width();
567
568 // set the scaling factor for now, this can be adjusted
569 // in the SetRange functions
570 m_dVerticalFactor = (double)m_nPlotHeight / m_dRange;
571 }
572
573
574 /////////////////////////////////////////////////////////////////////////////
575 void TGraphCtrl::Reset()
576 {
577 // to clear the existing data (in the form of a bitmap)
578 // simply invalidate the entire control
579 InvalidateCtrl();
580 }
581
582
583 extern TGraphCtrl PerformancePageCpuUsageHistoryGraph;
584 extern TGraphCtrl PerformancePageMemUsageHistoryGraph;
585 extern HWND hPerformancePageCpuUsageHistoryGraph;
586 extern HWND hPerformancePageMemUsageHistoryGraph;
587
588 LRESULT CALLBACK GraphCtrl_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
589 {
590 RECT rcClient;
591 HDC hdc;
592 PAINTSTRUCT ps;
593 //LONG WindowId;
594 //TGraphCtrl* pGraphCtrl;
595
596 switch (message) {
597 case WM_ERASEBKGND:
598 return TRUE;
599 //
600 // Filter out mouse & keyboard messages
601 //
602 //case WM_APPCOMMAND:
603 case WM_CAPTURECHANGED:
604 case WM_LBUTTONDBLCLK:
605 case WM_LBUTTONDOWN:
606 case WM_LBUTTONUP:
607 case WM_MBUTTONDBLCLK:
608 case WM_MBUTTONDOWN:
609 case WM_MBUTTONUP:
610 case WM_MOUSEACTIVATE:
611 case WM_MOUSEHOVER:
612 case WM_MOUSELEAVE:
613 case WM_MOUSEMOVE:
614 //case WM_MOUSEWHEEL:
615 case WM_NCHITTEST:
616 case WM_NCLBUTTONDBLCLK:
617 case WM_NCLBUTTONDOWN:
618 case WM_NCLBUTTONUP:
619 case WM_NCMBUTTONDBLCLK:
620 case WM_NCMBUTTONDOWN:
621 case WM_NCMBUTTONUP:
622 //case WM_NCMOUSEHOVER:
623 //case WM_NCMOUSELEAVE:
624 case WM_NCMOUSEMOVE:
625 case WM_NCRBUTTONDBLCLK:
626 case WM_NCRBUTTONDOWN:
627 case WM_NCRBUTTONUP:
628 //case WM_NCXBUTTONDBLCLK:
629 //case WM_NCXBUTTONDOWN:
630 //case WM_NCXBUTTONUP:
631 case WM_RBUTTONDBLCLK:
632 case WM_RBUTTONDOWN:
633 case WM_RBUTTONUP:
634 //case WM_XBUTTONDBLCLK:
635 //case WM_XBUTTONDOWN:
636 //case WM_XBUTTONUP:
637 case WM_ACTIVATE:
638 case WM_CHAR:
639 case WM_DEADCHAR:
640 case WM_GETHOTKEY:
641 case WM_HOTKEY:
642 case WM_KEYDOWN:
643 case WM_KEYUP:
644 case WM_KILLFOCUS:
645 case WM_SETFOCUS:
646 case WM_SETHOTKEY:
647 case WM_SYSCHAR:
648 case WM_SYSDEADCHAR:
649 case WM_SYSKEYDOWN:
650 case WM_SYSKEYUP:
651 return 0;
652
653 case WM_NCCALCSIZE:
654 return 0;
655
656 case WM_SIZE:
657 // pGraphCtrl = TGraphCtrl::LookupGraphCtrl(hWnd);
658 // if (pGraphCtrl) pGraphCtrl->Resize(wParam, HIWORD(lParam), LOWORD(lParam));
659 if (hWnd == hPerformancePageMemUsageHistoryGraph) {
660 PerformancePageMemUsageHistoryGraph.Resize();
661 PerformancePageMemUsageHistoryGraph.InvalidateCtrl();
662 }
663 if (hWnd == hPerformancePageCpuUsageHistoryGraph) {
664 PerformancePageCpuUsageHistoryGraph.Resize();
665 PerformancePageCpuUsageHistoryGraph.InvalidateCtrl();
666 }
667 return 0;
668 break;
669
670 case WM_PAINT:
671 hdc = BeginPaint(hWnd, &ps);
672 // pGraphCtrl = TGraphCtrl::LookupGraphCtrl(hWnd);
673 // if (pGraphCtrl) pGraphCtrl->Paint(hdc);
674 GetClientRect(hWnd, &rcClient);
675 if (hWnd == hPerformancePageMemUsageHistoryGraph) {
676 PerformancePageMemUsageHistoryGraph.Paint(hWnd, hdc);
677 }
678 if (hWnd == hPerformancePageCpuUsageHistoryGraph) {
679 PerformancePageCpuUsageHistoryGraph.Paint(hWnd, hdc);
680 }
681 EndPaint(hWnd, &ps);
682 return 0;
683 }
684
685 //
686 // We pass on all non-handled messages
687 //
688 return CallWindowProc((WNDPROC)OldGraphCtrlWndProc, hWnd, message, wParam, lParam);
689 }
690
691
692 #if 0
693
694 #include "GraphCtrl.h"
695
696 TGraphCtrl* TGraphCtrl::pCtrlArray[] = { 0, 0, 0, 0 };
697 int TGraphCtrl::CtrlCount = 0;
698
699 TGraphCtrl* TGraphCtrl::LookupGraphCtrl(HWND hWnd)
700 {
701 for (int i = 0; i < MAX_CTRLS; i++) {
702 if (pCtrlArray[i] != 0) {
703 if (pCtrlArray[i]->m_hParentWnd == hWnd) {
704 return pCtrlArray[i];
705 }
706 }
707 }
708 return NULL;
709 }
710
711 #endif
712