/***************************************************************************** * * Copyright (c) 1999, KL GROUP INC. All Rights Reserved. * http://www.klgroup.com * * This file is provided for demonstration and educational uses only. * Permission to use, copy, modify and distribute this file for * any purpose and without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies, and that the name of KL Group not be used in advertising * or publicity pertaining to this material without the specific, * prior written permission of an authorized representative of * KL Group. * * KL GROUP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. KL GROUP SHALL NOT BE LIABLE FOR ANY * DAMAGES SUFFERED BY USERS AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ // perfView.cpp : implementation of the CPerfView class // #include "stdafx.h" #include #include #include "perf.h" #include "2dconst.h" #include "DerivedDouble.h" #include "Axis.h" #include "AxisCollection.h" #include "AxisStyle.h" #include "ChartArea.h" #include "Chart2DData.h" #include "ChartGroup.h" #include "ChartGroupCollection.h" #include "SymbolStyle.h" #include "ChartStyle.h" #include "ChartStyleCollection.h" #include "Label.h" #include "LabelCollection.h" #include "Border.h" #include "Interior.h" #include "LineStyle.h" #include "Legend.h" #include "Font.h" #include "perfDoc.h" #include "perfView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPerfView IMPLEMENT_DYNCREATE(CPerfView, CView) BEGIN_MESSAGE_MAP(CPerfView, CView) //{{AFX_MSG_MAP(CPerfView) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SIZE() ON_WM_ERASEBKGND() ON_WM_TIMER() //}}AFX_MSG_MAP ON_WM_QUERYNEWPALETTE() ON_WM_PALETTECHANGED() // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPerfView construction/destruction CPerfView::CPerfView() { // TODO: add construction code here } CPerfView::~CPerfView() { } BOOL CPerfView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CPerfView drawing void CPerfView::OnDraw(CDC* pDC) { CPerfDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here } ///////////////////////////////////////////////////////////////////////////// // CPerfView printing BOOL CPerfView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CPerfView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CPerfView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } void CPerfView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { //Print the chart using the DrawToDC function. //The chart is printed so that it fills the page in one dimension //and is centered in the other dimension. //The aspect ratio of the chart is maintained (unless pixels don't //have the same aspect ratio on the screen and the printer). CRect rect; m_chart.GetClientRect(rect); //BLOCK: Set up scale mode { int nPageWidth, nPageHeight; int nChartWidth, nChartHeight; long a, b; pDC->SetMapMode(MM_ANISOTROPIC); nPageWidth = pDC->GetDeviceCaps(HORZRES); nPageHeight = pDC->GetDeviceCaps(VERTRES); nChartWidth = rect.right - rect.left; nChartHeight = rect.bottom - rect.top; a = nPageHeight; a *= nChartWidth; b = nPageWidth; b *= nChartHeight; // PH/PW < GH/GW // or PH*GW < PW*GH if(a < b) { // Fill vertically, center horizontally. pDC->SetWindowExt(nChartHeight, nChartHeight); pDC->SetViewportExt(nPageHeight, nPageHeight); pDC->LPtoDP(rect); nChartWidth = rect.right - rect.left; pDC->SetViewportOrg((nPageWidth - nChartWidth) / 2, 0); } else { // Fill horizontally, center vertically. pDC->SetWindowExt(nChartWidth, nChartWidth); pDC->SetViewportExt(nPageWidth, nPageWidth); pDC->LPtoDP(rect); nChartHeight = rect.bottom - rect.top; pDC->SetViewportOrg(0, (nPageHeight - nChartHeight) / 2); } } m_chart.GetClientRect(rect); ::LPtoDP(pDC->GetSafeHdc(), (POINT*)(&rect), 2); m_chart.DrawToDC((long) pDC->GetSafeHdc(), oc2dFormatEnhMetafile, oc2dScaleToFit, rect.left, rect.top, (rect.right-rect.left), (rect.bottom-rect.top)); //CView::OnPrint(pDC, pInfo); } ///////////////////////////////////////////////////////////////////////////// // CPerfView diagnostics #ifdef _DEBUG void CPerfView::AssertValid() const { CView::AssertValid(); } void CPerfView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CPerfDoc* CPerfView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPerfDoc))); return (CPerfDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CPerfView message handlers int CPerfView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) { return -1; } if (!m_chart.Create(NULL, WS_VISIBLE, CRect(0, 0, 100, 100), this, 1)) { return -1; } m_nTimerId = SetTimer(1, 1000, NULL); m_lArraySize = 50; m_lShiftSize = 40; m_lNextPoint = 0; m_lNextX = 0; // Don't allow the user to change any of the following (block the property pages) m_chart.SetAllowUserChanges(FALSE); // set up the colors and border styles m_chart.GetInterior().SetBackgroundColor(RGB(245, 222, 179)); m_chart.GetChartArea().GetInterior().SetBackgroundColor(RGB(247, 206, 151)); m_chart.GetChartArea().GetBorder().SetType(oc2dBorderShadow); m_chart.GetLegend().GetInterior().SetBackgroundColor(RGB(210, 180, 140)); m_chart.GetLegend().GetBorder().SetType(oc2dBorderShadow); m_chart.GetLegend().GetBorder().SetWidth(4); // Set the legend font point size CY cy; cy.Lo = 100000; cy.Hi = 0; m_chart.GetLegend().GetFont().SetSize(cy); // Get some useful subobjects CAxis axisX(m_chart.GetChartArea().GetAxes().GetItem(COleVariant("x"))); CAxis axisY(m_chart.GetChartArea().GetAxes().GetItem(COleVariant("y"))); CChart2DData data(m_chart.GetChartGroups().GetItem(COleVariant(short(1))).GetData()); CLabelCollection seriesLabels(m_chart.GetChartGroups().GetItem(COleVariant(short(1))).GetSeriesLabels()); VARIANT va; VariantInit(&va); va.vt = VT_I4; // Add Legend labels va.lVal = seriesLabels.GetCount() + 1; // just kidding!! seriesLabels.Add("HiTech Stock Price", va); va.lVal = seriesLabels.GetCount() + 1; seriesLabels.Add("Memory Load", va); va.lVal = seriesLabels.GetCount() + 1; seriesLabels.Add("Avail Physical Memory", va); va.lVal = seriesLabels.GetCount() + 1; seriesLabels.Add("Avail Paging File", va); axisY.GetMin().SetValue(0); axisY.GetMax().SetValue(100); axisX.GetMin().SetValue(0); axisX.GetMax().SetValue(m_lArraySize - 1); // Batch the Data Object for efficiency data.SetIsBatched(TRUE); data.SetLayout(oc2dDataArray); data.SetNumSeries(4); data.SetNumPoints(1, m_lArraySize); data.SetFirstSeries(1); data.SetLastSeries(data.GetNumSeries()); data.SetFirstPoint(1, 1); data.SetLastPoint(1, 0); data.SetX(1, 1, 0); for (int i = 1; i <= data.GetNumSeries(); i++) { data.SetY(i, 1, 0); } data.SetIsBatched(FALSE); for (i = 1; i <= data.GetNumSeries(); i++) { CChartStyle style(m_chart.GetChartGroups().GetItem(COleVariant(short(1))).GetStyles().GetItem(COleVariant(short(i)))); // Clear the shape style style.GetSymbol().SetShape(oc2dShapeNone); // Make the lines thicker style.GetLine().SetWidth(3); } // Change this color to not conflict with the legend background CChartStyle style(m_chart.GetChartGroups().GetItem(COleVariant(short(1))).GetStyles().GetItem(COleVariant(short(2)))); style.GetLine().SetColor(RGB(255, 255, 0)); // Demonstration of some additional features added in version 6.0: // Set the legend title m_chart.GetLegend().GetText().SetText("Series"); // Set longer X axis ticks (normally set to 2) axisX.GetAxisStyle().SetTickLength(4); // Set the Y axis to "forest green" axisY.GetAxisStyle().GetLineStyle().SetColor(RGB(34,139,34)); // Rotate the X axis annotations by 30 degrees. axisX.SetAnnotationRotationAngle(30.0); // Enable these lines to stack (or 100% stack) the series. // Note that if your memory load is always 0, that series may be hidden behind the "stock" series. /* m_chart.GetChartGroups().GetItem(COleVariant(short(1))).SetIsStacked(TRUE); axisY.SetIs100Percent(TRUE); */ return 0; } void CPerfView::OnDestroy() { CView::OnDestroy(); // Clean up any outstanding timers KillTimer(m_nTimerId); } void CPerfView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // Size the chart to fit the window if ((cx > 0) && (cy > 0)) { m_chart.MoveWindow(0, 0, cx, cy); } } // Pass palette messages back to the control for proper color updating BOOL CPerfView::OnQueryNewPalette() { return(m_chart.SendMessage(WM_QUERYNEWPALETTE, 0, 0)); } void CPerfView::OnPaletteChanged(CWnd* pFocusWnd) { m_chart.SendMessage(WM_PALETTECHANGED, (WPARAM)pFocusWnd->GetSafeHwnd(), 0); } // We paint all of our background BOOL CPerfView::OnEraseBkgnd(CDC* pDC) { return TRUE; } void CPerfView::OnTimer(UINT nIDEvent) { if (nIDEvent == 1) { CAxis axisX(m_chart.GetChartArea().GetAxes().GetItem(COleVariant("x"))); CChart2DData data(m_chart.GetChartGroups().GetItem(COleVariant(short(1))).GetData()); double dMinimum; // The new points will not fit if (data.GetLastPoint(1) >= data.GetNumPoints(1)) { // Move the current points to the left. m_chart.SetIsBatched(TRUE); data.ShiftPoints(1, m_lShiftSize, 1, m_lArraySize - m_lShiftSize + 1); m_lNextPoint = m_lShiftSize + 1; dMinimum = axisX.GetMin().GetValue(); dMinimum += m_lArraySize - m_lShiftSize; axisX.GetMin().SetValue(dMinimum); axisX.GetMax().SetValue(dMinimum + m_lArraySize - 1); data.SetLastPoint(1, m_lShiftSize); m_chart.SetIsBatched(FALSE); } // if else { m_lNextPoint = data.GetLastPoint(1) + 1; } // else data.SetX(1, m_lNextPoint, m_lNextX); double dValue; MEMORYSTATUS ms; ms.dwLength = sizeof(ms); GlobalMemoryStatus(&ms); dValue = ((double) rand() / RAND_MAX) * 100; data.SetY(1, m_lNextPoint, dValue); data.SetY(2, m_lNextPoint, ms.dwMemoryLoad); dValue = ((double) ms.dwTotalPhys - ms.dwAvailPhys) / ms.dwTotalPhys * 100; data.SetY(3, m_lNextPoint, dValue); dValue = ((double) ms.dwTotalPageFile - ms.dwAvailPageFile) / ms.dwTotalPageFile * 100; data.SetY(4, m_lNextPoint, dValue); m_lNextPoint += 1; m_lNextX += 1; data.DrawNewPoints(1, 1); } // if CView::OnTimer(nIDEvent); }