chartwnd.cpp

来自「The application wizard has created this 」· C++ 代码 · 共 552 行 · 第 1/2 页

CPP
552
字号
/************************************************************************************************
// $Header: /home/cvsroot/SoccerDoctor/Chart/ChartWnd.cpp,v 1.5 2002/09/10 06:44:35 peter Exp $
//***********************************************************************************************
/************************************************************************************************/
/*                                                                                              */
/* File    : ChartWnd.cpp                                                                       */
/*                                                                                              */
/* Purpose : interface for the plot area of the CChartCtrl                                      */
/*                                                                                              */
/* Author  : Scott Pelger                                             Date Created: 10JUN02     */
/*                                                                                              */
/* Revisions                                                                                    */
/*                                                                                              */
/* Engineer              Date        Description                                                */
/*                                                                                              */
/* Scott Pelger          10JUN02     initial version                                            */
/*                                                                                              */
/************************************************************************************************/
#include "stdafx.h"
#include "ChartWnd.h"
#include <time.h>
#include "MemDC.h"

CChartWnd::CChartWnd() : 
    m_Axis(), 
    m_pYAxisFont(NULL), 
    m_bRotate(FALSE), 
    m_eStyle(SHOW_POPUP_WINDOWS_BR),
    m_pCurrentDataPoint(NULL),
    m_bScrolling(FALSE),
    m_bRefreshDisplayCompletely(FALSE) {}

CChartWnd::~CChartWnd() {
    
	if (m_pYAxisFont){
		m_pYAxisFont->DeleteObject();
        delete m_pYAxisFont;
	}
	m_GraphBitmap.DeleteObject();
	m_WholeBitmap.DeleteObject();
}

BEGIN_MESSAGE_MAP(CChartWnd, CChartWndBase)
	//{{AFX_MSG_MAP(CChartWnd)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_LBUTTONDBLCLK()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/************************************************************************************************/
/*                                                                                              */
/* Function: CChartWnd::DrawChart()                                                             */
/*                                                                                              */
/* Purpose : carries out the grunt work of drawing the chart using a mem dc to prevent the      */
/*           control from flickering. after the control is completely drawn a copy is made to   */
/*           be used in OnPaint for fast updates.                                               */
/*                                                                                              */
/* Inputs  : NONE                                                                               */
/*                                                                                              */
/* Outputs : NONE                                                                               */
/*                                                                                              */
/* Author  : Scott Pelger                                             Date Created: 15MAY02     */
/*                                                                                              */
/* Revisions                                                                                    */
/*                                                                                              */
/* Engineer              Date        Description                                                */
/*                                                                                              */
/* Scott Pelger          15MAY02     initial version                                            */
/*                                                                                              */
/************************************************************************************************/
void CChartWnd::DrawChart() {

    CClientDC dc(this);
    
    /****set up the memory DC****/
    CMemDC      memDC(&dc);
	CBitmap     memBitmap;
    CRect       rcClient;
    GetClientRect(&rcClient);
    int nRectWidth(rcClient.Width());
    int nRectHeight(rcClient.Height());
	    
    m_rcClientRect = rcClient;
    memBitmap.CreateCompatibleBitmap(&dc, nRectWidth, nRectHeight);
    
    CBitmap* pOldBitmap = memDC.SelectObject(&memBitmap);
    /****set up the memory DC****/

    memDC.FillSolidRect(&m_rcClientRect, m_crWindowColor);
    memDC.SelectObject(m_pFont);
    memDC.SetTextColor(m_crTextColor);
    
    m_rcClientRect.DeflateRect(5, 5);
    
    if (TYPE_BAR==m_DataSeriesArray.GetChartType()) {
        m_Axis.SetAxisScale(X_AXIS, 0, m_DataSeriesArray.GetMaxInAllSeries()+1);
        m_Axis.SetScaleStep(X_AXIS, 1, 1);
        }
    
    m_Axis.DrawAxis(&memDC, &m_rcClientRect);
    
    //if the vertical scaling has changed we need to force
    //a complete redraw of the chart, if we are not scrolling
    //then we always do a full redraw
	if (m_Axis.HasVerticalScalingChanged()){
        m_bRefreshDisplayCompletely = !(m_bScrolling = FALSE);
	}
    
    m_DataSeriesArray.DrawData(&memDC, &m_Axis);
    m_DataSeriesArray.DrawIcons(&memDC, &m_Axis);
    
    
    dc.BitBlt(rcClient.left, rcClient.top, nRectWidth, nRectHeight, &memDC, 0, 0, SRCCOPY);
    
	if (m_DataSeriesArray.DataRemoved()&&TYPE_STRIP_CHART_FILLED==m_eChartType){
        m_bScrolling = TRUE;
	}

	// memDC 和 memDC2 析构的顺序不同导致GDI资源泄漏,maybe
	CMemDC memDC2(&memDC);
	m_PlotRect = m_Axis.GetRect();
    m_GraphBitmap.DeleteObject();
    m_GraphBitmap.CreateCompatibleBitmap(&dc, m_PlotRect.Width(), m_PlotRect.Height());
    memDC2.SelectObject(&m_GraphBitmap);
    memDC2.BitBlt(0, 0, m_PlotRect.Width(), m_PlotRect.Height(), &memDC, m_PlotRect.left, m_PlotRect.top, SRCCOPY);
    
    
    //next, let's make a copy of the entire chart window for fast OnPaint() updates
    GetClientRect(&rcClient);
    
    m_WholeBitmap.DeleteObject();
    m_WholeBitmap.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
    memDC2.SelectObject(&m_WholeBitmap);
    memDC2.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);

	// 防止资源泄漏
    memDC.SelectObject(pOldBitmap);
	memBitmap.DeleteObject();
}

void CChartWnd::OnPaint() {
	
    CRect rcClient;
    GetClientRect(&rcClient);
    
    CPaintDC dc(this);

    CMemDC memDC(&dc);
    memDC.SelectObject(&m_WholeBitmap);
    dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
}

/************************************************************************************************/
/*                                                                                              */
/* Function: CChartWnd::SetFont()                                                               */
/*                                                                                              */
/* Purpose : carries out the grunt work of drawing the chart using a mem dc to prevent the      */
/*           control from flickering. after the control is completely drawn a copy is made to   */
/*           be used in OnPaint for fast updates.                                               */
/*                                                                                              */
/* Inputs  : BYTE byPointSize -> desired point size of font                                     */
/*           char* psFontName -> desired font name to use                                       */
/*           BYTE byStyle -> desired styles of font such as BOLD, ITALIC, and UNDERLINE         */
/*                                                                                              */
/* Outputs : BOOL <- TRUE if an error occured, FALSE otherwise                                  */
/*                                                                                              */
/* Author  : Scott Pelger                                             Date Created: 15MAY02     */
/*                                                                                              */
/* Revisions                                                                                    */
/*                                                                                              */
/* Engineer              Date        Description                                                */
/*                                                                                              */
/* Scott Pelger          15MAY02     initial version                                            */
/*                                                                                              */
/************************************************************************************************/
BOOL CChartWnd::SetFont(BYTE byPointSize, char* psFontName, BYTE byStyle/*=0*/) {

    CChartWndBase::SetFont(byPointSize, psFontName, byStyle);

    if (m_pYAxisFont)
        m_pYAxisFont->DeleteObject();
    
    if (!m_pYAxisFont) {
        m_pYAxisFont = new CFont;
        if (!m_pYAxisFont)
            return TRUE;
        }
    
    LOGFONT lf;
    
    memset(&lf, 0, sizeof(LOGFONT));
        
    strcpy(lf.lfFaceName, psFontName);

    lf.lfHeight     = byPointSize*10;
    lf.lfWeight     = byStyle&BOLD?FW_BOLD:FW_NORMAL;
    lf.lfItalic     = byStyle&ITALIC;
    lf.lfUnderline  = byStyle&UNDERLINE;
    lf.lfOrientation = 900;
    lf.lfEscapement  = 900;
  
    CClientDC dc(this);

    m_pYAxisFont->CreatePointFontIndirect(&lf, &dc);

    m_Axis.m_pYAxisFont = m_pYAxisFont;
    m_Axis.m_pFont = m_pFont;

    return FALSE;
    }

/************************************************************************************************/
/*                                                                                              */
/* Function: CChartWnd::_DataPointHitTest()                                                     */
/*                                                                                              */
/* Purpose : cycles through all data points and determines if this point lies within it's       */
/*           detect region                                                                      */
/*                                                                                              */
/* Inputs  : CPoint& Point -> the point to test                                                 */
/*                                                                                              */
/* Outputs : CDataPoint* <- pointer to the data point if found                                  */
/*                                                                                              */
/* Author  : Scott Pelger                                             Date Created: 12JUN02     */
/*                                                                                              */
/* Revisions                                                                                    */
/*                                                                                              */
/* Engineer              Date        Description                                                */
/*                                                                                              */
/* Scott Pelger          12JUN02     initial version                                            */
/* Scott Pelger          27JUN02     return NULL if chart is any strip chart                    */
/* Scott Pelger          28JUN02     force nNumberOfSeries to 1 if chart is any pie chart,      */
/*                                   skip data series' that contain no data points              */
/*                                                                                              */
/************************************************************************************************/    
CDataPoint* CChartWnd::_DataPointHitTest(CPoint& Point) {

    if (TYPE_STRIP_CHART        ==m_DataSeriesArray.GetChartType()||
        TYPE_STRIP_CHART_FILLED ==m_DataSeriesArray.GetChartType())
        return NULL;

    int nNumberOfSeries(m_DataSeriesArray.GetCount());
    int nNumberInSeries(m_DataSeriesArray.GetMaxInAllSeries());

    CDataSeries* pDataSeries = NULL;
    CDataPoint* pDataPoint = NULL;
    
    if (TYPE_PIE        ==m_DataSeriesArray.GetChartType()||
        TYPE_ROTATED_PIE==m_DataSeriesArray.GetChartType())
        nNumberOfSeries = 1;

    for (int i(nNumberOfSeries-1);i>-1;i--) {
        if (!(pDataSeries = (CDataSeries*)m_DataSeriesArray.GetDataSeries(i)))
            continue;
        
        for (int j(nNumberInSeries-1);j>-1;j--) {
            //if no data points in this series skip on to the next
            if (!(pDataSeries->GetCount()))
                break;
            
            if (!(pDataPoint = pDataSeries->GetAt(j)))
                continue;

            if (TYPE_AREA==m_eChartType) {
                //for area chart we only have one data point to test for
                if (!(pDataPoint = pDataSeries->GetAt(0)))
                    continue;
                }
            
            if (pDataPoint->m_DetectRegion.PtInRegion(Point))
                return pDataPoint;
            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?