6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
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.
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.
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.
25 #include "GraphCtrl.h"
31 static char THIS_FILE
[] = __FILE__
;
35 LONG OldGraphCtrlWndProc
;
38 TGraphCtrl::TGraphCtrl() :
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;
67 // public variable for the number of decimal places on the y axis
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;
76 m_dUpperLimit
= 100.0;
77 m_dRange
= m_dUpperLimit
- m_dLowerLimit
; // protected member variable
79 // m_nShiftPixels determines how much the plot shifts (in terms of pixels)
80 // with the addition of a new data point
82 m_nHalfShiftPixels
= m_nShiftPixels
/2; // protected
83 m_nPlotShiftPixels
= m_nShiftPixels
+ m_nHalfShiftPixels
; // protected
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
94 // protected variables
96 for (i
= 0; i
< MAX_PLOTS
; i
++) {
97 m_penPlot
[i
] = CreatePen(PS_SOLID
, 0, m_crPlotColor
[i
]);
99 m_brushBack
= CreateSolidBrush(m_crBackColor
);
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
105 // protected bitmaps to restore the memory DC's
106 m_bitmapOldGrid
= NULL
;
107 m_bitmapOldPlot
= NULL
;
109 for (i
= 0; i
< MAX_CTRLS
; i
++) {
110 if (pCtrlArray
[i
] == 0) {
111 pCtrlArray
[i
] = this;
117 /////////////////////////////////////////////////////////////////////////////
118 TGraphCtrl::~TGraphCtrl()
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
);
130 for (int i
= 0; i
< MAX_CTRLS
; i
++) {
131 if (pCtrlArray
[i
] == this) {
138 /////////////////////////////////////////////////////////////////////////////
139 BOOL
TGraphCtrl::Create(HWND hWnd
, HWND hParentWnd
, UINT nID
)
143 m_hParentWnd
= hParentWnd
;
152 BOOL TGraphCtrl::Create(DWORD dwStyle, const RECT& rect,
153 HWND hParentWnd, UINT nID)
157 m_hParentWnd = hParentWnd;
158 // GetClientRect(m_hParentWnd, &m_rectClient);
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;
166 // the "left" coordinate and "width" will be modified in
167 // InvalidateCtrl to be based on the width of the y axis scaling
169 m_rectPlot.left = 20;
171 m_rectPlot.right = rect.right-10;
172 m_rectPlot.bottom = rect.bottom-25;
174 m_rectPlot.left = -1;
176 m_rectPlot.right = rect.right-0;
177 m_rectPlot.bottom = rect.bottom-0;
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();
183 // set the scaling factor for now, this can be adjusted
184 // in the SetRange functions
185 m_dVerticalFactor = (double)m_nPlotHeight / m_dRange;
192 /////////////////////////////////////////////////////////////////////////////
193 void TGraphCtrl::SetRange(double dLower
, double dUpper
, int nDecimalPlaces
)
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
206 /////////////////////////////////////////////////////////////////////////////
207 void TGraphCtrl::SetXUnits(const char* string
)
209 strncpy(m_strXUnitsString
, string
, sizeof(m_strXUnitsString
) - 1);
210 // clear out the existing garbage, re-start with a clean plot
214 /////////////////////////////////////////////////////////////////////////////
215 void TGraphCtrl::SetYUnits(const char* string
)
217 strncpy(m_strYUnitsString
, string
, sizeof(m_strYUnitsString
) - 1);
218 // clear out the existing garbage, re-start with a clean plot
222 /////////////////////////////////////////////////////////////////////////////
223 void TGraphCtrl::SetGridColor(COLORREF color
)
225 m_crGridColor
= color
;
226 // clear out the existing garbage, re-start with a clean plot
230 /////////////////////////////////////////////////////////////////////////////
231 void TGraphCtrl::SetPlotColor(int plot
, COLORREF color
)
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
240 /////////////////////////////////////////////////////////////////////////////
241 void TGraphCtrl::SetBackgroundColor(COLORREF color
)
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
251 /////////////////////////////////////////////////////////////////////////////
252 void TGraphCtrl::InvalidateCtrl()
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.
259 int nTopGridPix
, nMidGridPix
, nBottomGridPix
;
262 HPEN solidPen
= CreatePen(PS_SOLID
, 0, m_crGridColor
);
263 //HFONT axisFont, yUnitFont, oldFont;
266 // in case we haven't established the memory dc's
267 //CClientDC dc(this);
268 HDC dc
= GetDC(m_hParentWnd
);
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
);
277 SetBkColor(m_dcGrid
, m_crBackColor
);
279 // fill the grid background
280 FillRect(m_dcGrid
, &m_rectClient
, m_brushBack
);
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
))));
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
;
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();
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
);
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;
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
);
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);
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
,
337 DEFAULT_PITCH
|FF_SWISS
, "Arial");
338 yUnitFont
= CreateFont (14, 0, 900, 0, 300,
339 FALSE
, FALSE
, 0, ANSI_CHARSET
,
343 DEFAULT_PITCH
|FF_SWISS
, "Arial");
345 // grab the horizontal font
346 oldFont
= (HFONT
)SelectObject(m_dcGrid
, axisFont
);
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
));
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
));
360 SetTextAlign(m_dcGrid
, TA_LEFT
|TA_TOP
);
361 TextOut(m_dcGrid
, m_rectPlot
.left
, m_rectPlot
.bottom
+4, "0", 1);
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
));
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
));
374 SelectObject(m_dcGrid
, oldFont
);
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
);
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
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
);
393 // make sure the plot bitmap is cleared
394 SetBkColor(m_dcPlot
, m_crBackColor
);
395 FillRect(m_dcPlot
, &m_rectClient
, m_brushBack
);
397 // finally, force the plot area to redraw
398 InvalidateRect(m_hParentWnd
, &m_rectClient
, TRUE
);
399 ReleaseDC(m_hParentWnd
, dc
);
403 /////////////////////////////////////////////////////////////////////////////
404 double TGraphCtrl::AppendPoint(double dNewPoint0
, double dNewPoint1
,
405 double dNewPoint2
, double dNewPoint3
)
407 // append a data point to the plot & return the previous point
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
;
421 ////////////////////////////////////////////////////////////////////////////
422 void TGraphCtrl::Paint(HWND hWnd
, HDC dc
)
426 HBITMAP oldBitmap
; // bitmap originally found in CMemDC
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;
434 // no real plotting work is performed here,
435 // just putting the existing bitmaps on the client
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
);
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
);
452 SelectObject(memDC
, oldBitmap
);
453 DeleteObject(memBitmap
);
457 /////////////////////////////////////////////////////////////////////////////
458 void TGraphCtrl::DrawPoint()
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
465 int currX
, prevX
, currY
, prevY
;
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
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,
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
;
487 // fill the cleanup area with the background
488 FillRect(m_dcPlot
, &rectCleanUp
, m_brushBack
);
490 // draw the next line segement
491 for (int i
= 0; i
< MAX_PLOTS
; i
++) {
493 // grab the plotting pen
494 oldPen
= (HPEN
)SelectObject(m_dcPlot
, m_penPlot
[i
]);
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
);
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
);
509 SelectObject(m_dcPlot
, oldPen
);
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
516 if ((prevY
<= m_rectPlot
.top
) || (currY
<= m_rectPlot
.top
)) {
518 rc
.bottom
= m_rectPlot
.top
+1;
521 rc
.top
= m_rectClient
.top
;
522 FillRect(m_dcPlot
, &rc
, m_brushBack
);
524 if ((prevY
>= m_rectPlot
.bottom
) || (currY
>= m_rectPlot
.bottom
)) {
526 rc
.bottom
= m_rectClient
.bottom
+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
);
534 // store the current point for connection to the next point
535 m_dPreviousPosition
[i
] = m_dCurrentPosition
[i
];
540 /////////////////////////////////////////////////////////////////////////////
541 void TGraphCtrl::Resize(void)
543 // NOTE: Resize automatically gets called during the setup of the control
544 GetClientRect(m_hWnd
, &m_rectClient
);
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();
550 // the "left" coordinate and "width" will be modified in
551 // InvalidateCtrl to be based on the width of the y axis scaling
553 m_rectPlot
.left
= 20;
555 m_rectPlot
.right
= m_rectClient
.right
-10;
556 m_rectPlot
.bottom
= m_rectClient
.bottom
-25;
560 m_rectPlot
.right
= m_rectClient
.right
-0;
561 m_rectPlot
.bottom
= m_rectClient
.bottom
-0;
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();
568 // set the scaling factor for now, this can be adjusted
569 // in the SetRange functions
570 m_dVerticalFactor
= (double)m_nPlotHeight
/ m_dRange
;
574 /////////////////////////////////////////////////////////////////////////////
575 void TGraphCtrl::Reset()
577 // to clear the existing data (in the form of a bitmap)
578 // simply invalidate the entire control
583 extern TGraphCtrl PerformancePageCpuUsageHistoryGraph
;
584 extern TGraphCtrl PerformancePageMemUsageHistoryGraph
;
585 extern HWND hPerformancePageCpuUsageHistoryGraph
;
586 extern HWND hPerformancePageMemUsageHistoryGraph
;
588 LRESULT CALLBACK
GraphCtrl_WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
594 //TGraphCtrl* pGraphCtrl;
600 // Filter out mouse & keyboard messages
602 //case WM_APPCOMMAND:
603 case WM_CAPTURECHANGED
:
604 case WM_LBUTTONDBLCLK
:
607 case WM_MBUTTONDBLCLK
:
610 case WM_MOUSEACTIVATE
:
614 //case WM_MOUSEWHEEL:
616 case WM_NCLBUTTONDBLCLK
:
617 case WM_NCLBUTTONDOWN
:
619 case WM_NCMBUTTONDBLCLK
:
620 case WM_NCMBUTTONDOWN
:
622 //case WM_NCMOUSEHOVER:
623 //case WM_NCMOUSELEAVE:
625 case WM_NCRBUTTONDBLCLK
:
626 case WM_NCRBUTTONDOWN
:
628 //case WM_NCXBUTTONDBLCLK:
629 //case WM_NCXBUTTONDOWN:
630 //case WM_NCXBUTTONUP:
631 case WM_RBUTTONDBLCLK
:
634 //case WM_XBUTTONDBLCLK:
635 //case WM_XBUTTONDOWN:
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();
663 if (hWnd
== hPerformancePageCpuUsageHistoryGraph
) {
664 PerformancePageCpuUsageHistoryGraph
.Resize();
665 PerformancePageCpuUsageHistoryGraph
.InvalidateCtrl();
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
);
678 if (hWnd
== hPerformancePageCpuUsageHistoryGraph
) {
679 PerformancePageCpuUsageHistoryGraph
.Paint(hWnd
, hdc
);
686 // We pass on all non-handled messages
688 return CallWindowProc((WNDPROC
)OldGraphCtrlWndProc
, hWnd
, message
, wParam
, lParam
);
694 #include "GraphCtrl.h"
696 TGraphCtrl
* TGraphCtrl::pCtrlArray
[] = { 0, 0, 0, 0 };
697 int TGraphCtrl::CtrlCount
= 0;
699 TGraphCtrl
* TGraphCtrl::LookupGraphCtrl(HWND hWnd
)
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
];