博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ChartCtrl源码剖析之——CChartLegend类
阅读量:4635 次
发布时间:2019-06-09

本文共 9499 字,大约阅读时间需要 31 分钟。

CChartLegend类用来绘制每一个波形的描述信息,它处于该控件的区域,如下图所示: 

CChartLegend类的头文件。

#if !defined(AFX_CHARTLEGEND_H__CD72E5A0_8F52_472A_A611_C588F642080B__INCLUDED_)#define AFX_CHARTLEGEND_H__CD72E5A0_8F52_472A_A611_C588F642080B__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "ChartObject.h"#include "ChartCtrl.h"#include "ChartString.h"class CChartSerie;class CChartLegend : public CChartObject  {    friend CChartCtrl;public:    void SetFont(int iPointSize, const TChartString& strFaceName);    CChartLegend(CChartCtrl* pParent);    virtual ~CChartLegend();    enum DockSide    {        dsDockRight,        dsDockLeft,        dsDockTop,        dsDockBottom    };    void DockLegend(DockSide dsSide);    void UndockLegend(int iLeftPos, int iTopPos);    void SetTransparent(bool bTransparent);      void SetHorizontalMode(bool bHorizontal);private:    void Draw(CDC* pDC);    void ClipArea(CRect& rcControl, CDC* pDC);    void UpdatePosition(CDC* pDC, const CRect& rcControl);    TChartString m_strFontName;    int          m_iFontSize;    bool m_bDocked;    // true if the legend is docked    DockSide m_DockSide;    // If the legend is not docked:    int m_iLeftPos;    int m_iTopPos;    bool m_bIsTransparent;    bool m_bIsHorizontal;    CSize m_BitmapSize;};#endif // !defined(AFX_CHARTLEGEND_H__CD72E5A0_8F52_472A_A611_C588F642080B__INCLUDED_)

CChartLegend类的源文件。

#include "stdafx.h"#include "ChartLegend.h"#include "ChartSerie.h"#include "ChartCtrl.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//// Construction/Destruction//CChartLegend::CChartLegend(CChartCtrl* pParent):CChartObject(pParent){    m_ObjectColor = RGB(255,255,255);    m_iFontSize = 100;    m_strFontName = _T("Times New Roman");    m_bIsVisible = false;    m_bDocked = true;    m_DockSide = dsDockRight;    m_iLeftPos = m_iTopPos = 0;    m_bIsTransparent = false;    m_bIsHorizontal = false;    m_bShadow = true;    m_iShadowDepth = 3;    m_BitmapSize.cx = 16;    m_BitmapSize.cy = 16;}CChartLegend::~CChartLegend(){}void CChartLegend::SetFont(int iPointSize, const TChartString& strFaceName){    m_iFontSize = iPointSize;    m_strFontName = strFaceName;    m_pParent->RefreshCtrl();}void CChartLegend::SetTransparent(bool bTransparent){    m_bIsTransparent = bTransparent;    m_pParent->RefreshCtrl();}void CChartLegend::SetHorizontalMode(bool bHorizontal){    m_bIsHorizontal = bHorizontal;    m_pParent->RefreshCtrl();}void CChartLegend::DockLegend(DockSide dsSide){    m_bDocked = true;    m_DockSide = dsSide;    m_pParent->RefreshCtrl();}void CChartLegend::UndockLegend(int iLeftPos, int iTopPos){    m_bDocked = false;    m_iLeftPos = iLeftPos;    m_iTopPos = iTopPos;    m_pParent->RefreshCtrl();}void CChartLegend::ClipArea(CRect& rcControl, CDC* pDC){    UpdatePosition(pDC,rcControl);    if (m_ObjectRect.IsRectEmpty())        return;    if (m_bDocked)    {        switch (m_DockSide)        {        case dsDockRight:            rcControl.right = m_ObjectRect.left + 2;            break;        case dsDockLeft:            rcControl.left = m_ObjectRect.right - 2;            break;        case dsDockTop:            rcControl.top = m_ObjectRect.bottom + 2;            break;        case dsDockBottom:            rcControl.bottom = m_ObjectRect.top - 2;            break;        }    }}void CChartLegend::UpdatePosition(CDC* pDC, const CRect& rcControl){    CRect NewPosition;    NewPosition.SetRectEmpty();    if (!m_bIsVisible)    {        SetRect(NewPosition);        return;    }    CFont* pOldFont;    CFont NewFont;    NewFont.CreatePointFont(m_iFontSize,m_strFontName.c_str(),pDC);    pOldFont = pDC->SelectObject(&NewFont);    int Height = 0;            int Width = 0;            int MaxText = 0;    CSize TextSize;    size_t SeriesCount = m_pParent->GetSeriesCount();    int Drawn = 0;    for (size_t i=0;i
GetSerie(i); if ( (pSerie->GetName() == _T("")) || !pSerie->IsVisible() ) continue; Drawn++; TextSize = pDC->GetTextExtent(pSerie->GetName().c_str()); if (!m_bIsHorizontal) { if (TextSize.cy>m_BitmapSize.cy) Height += TextSize.cy + 2; else Height += m_BitmapSize.cy + 2; if (TextSize.cx > MaxText) MaxText = TextSize.cx; } else { Width += TextSize.cx + 4 + m_BitmapSize.cx + 10; if (TextSize.cy > MaxText) MaxText = TextSize.cy; } } pDC->SelectObject(pOldFont); DeleteObject(NewFont); if (!Drawn) { SetRect(NewPosition); return; } if (!m_bIsHorizontal) { Width += MaxText + m_BitmapSize.cx + 12; Height += 4 + 4 - 2; // Top and bottom margins. -2 because space counted once too much } else { Width += 2 + 2 - 10; Height = 4 + max(m_BitmapSize.cy,MaxText) + 4; } if (!m_bDocked) { NewPosition.top = m_iTopPos; NewPosition.left = m_iLeftPos; NewPosition.bottom = m_iTopPos + Height + 2; NewPosition.right = m_iLeftPos + Width; } else { switch (m_DockSide) { case dsDockRight: NewPosition.top = ((rcControl.bottom-rcControl.top)/2) - ((Height + 2)/2); NewPosition.left = rcControl.right - (Width + 6); NewPosition.bottom = NewPosition.top + Height; NewPosition.right = NewPosition.left + Width; break; case dsDockLeft: NewPosition.top = ((rcControl.bottom-rcControl.top)/2) - ((Height + 2)/2); NewPosition.left = rcControl.left + 3; NewPosition.bottom = NewPosition.top + Height; NewPosition.right = NewPosition.left + Width; break; case dsDockTop: NewPosition.top = rcControl.top + 3; //((rcControl.bottom-rcControl.top)/2) - ((Height + 2)/2); NewPosition.left = ((rcControl.right-rcControl.left)/2) - (Width/2); // rcControl.left + 3; NewPosition.bottom = NewPosition.top + Height; NewPosition.right = NewPosition.left + Width; break; case dsDockBottom: NewPosition.top = rcControl.bottom - (Height + 2); //((rcControl.bottom-rcControl.top)/2) - ((Height + 2)/2); NewPosition.left = ((rcControl.right-rcControl.left)/2) - (Width/2); // rcControl.left + 3; NewPosition.bottom = NewPosition.top + Height; NewPosition.right = NewPosition.left + Width; break; } } SetRect(NewPosition);}void CChartLegend::Draw(CDC *pDC){ if (!pDC->GetSafeHdc()) return; if (!m_bIsVisible) return; if (m_ObjectRect.IsRectEmpty()) return; CPen SolidPen(PS_SOLID,0,RGB(0,0,0)); CPen* pOldPen; CFont* pOldFont; CFont NewFont; NewFont.CreatePointFont(m_iFontSize,m_strFontName.c_str(),pDC); // Draw the shadow if (m_bShadow) { CRect ShadowRect = m_ObjectRect; ShadowRect.OffsetRect(m_iShadowDepth,m_iShadowDepth); CBrush BrushShadow; BrushShadow.CreateSolidBrush(m_ShadowColor) ; pDC->FillRect(ShadowRect,&BrushShadow); } if (!m_bIsTransparent) { //Fill back color CBrush BrushBack; BrushBack.CreateSolidBrush(m_ObjectColor) ; pDC->FillRect(m_ObjectRect,&BrushBack); } pOldFont = pDC->SelectObject(&NewFont); pOldPen = pDC->SelectObject(&SolidPen); //Draw rectangle: pDC->MoveTo(m_ObjectRect.left,m_ObjectRect.top); pDC->LineTo(m_ObjectRect.right,m_ObjectRect.top); pDC->LineTo(m_ObjectRect.right,m_ObjectRect.bottom); pDC->LineTo(m_ObjectRect.left,m_ObjectRect.bottom); pDC->LineTo(m_ObjectRect.left,m_ObjectRect.top); int iPrevMode = pDC->SetBkMode(TRANSPARENT); CRect rectBitmap(m_ObjectRect.left+2,m_ObjectRect.top+5, m_ObjectRect.left+2+m_BitmapSize.cx, m_ObjectRect.top+6+m_BitmapSize.cy); int SeriesCount = m_pParent->GetSeriesCount(); for (int i=0;i
GetSerie(i); if ( (pSerie->GetName() == _T("")) || !pSerie->IsVisible() ) continue; int MaxHeight = 0; CSize TextSize = pDC->GetTextExtent(pSerie->GetName().c_str()); if (TextSize.cy > m_BitmapSize.cy) { pDC->ExtTextOut(rectBitmap.right+4,rectBitmap.top,ETO_CLIPPED,NULL,pSerie->GetName().c_str(),NULL); CRect rectTemp(rectBitmap); int YOffset = TextSize.cy/2 - rectBitmap.Height()/2; rectTemp.OffsetRect(0,YOffset); pSerie->DrawLegend(pDC,rectTemp); MaxHeight = TextSize.cy; } else { int YOffset = rectBitmap.CenterPoint().y - TextSize.cy/2; pDC->ExtTextOut(rectBitmap.right+4,YOffset,ETO_CLIPPED,NULL,pSerie->GetName().c_str(),NULL); MaxHeight = m_BitmapSize.cy; pSerie->DrawLegend(pDC,rectBitmap); } if (!m_bIsHorizontal) rectBitmap.OffsetRect(0,MaxHeight+2); else rectBitmap.OffsetRect(m_BitmapSize.cx+4+TextSize.cx+10,0); } pDC->SetBkMode(iPrevMode); pDC->SelectObject(pOldFont); DeleteObject(NewFont); pDC->SelectObject(pOldPen); DeleteObject(SolidPen);}

ClipArea函数的作用是将ChartLegend与波形绘制区域分离开,其中rcControl表示的是绘制波形的区域,m_ObjectRect表示的是绘制ChartLegend的区域。UpdatePosition函数用来在当前绘制区域里面计算ChartLegend所处的位置并记录下该位置。Draw函数用来绘制ChartLegend控件,调用CChartSeries类的DrawLegend用来绘制ChartLegend里面的波形图像信息。 

转载于:https://www.cnblogs.com/wolfmvp/p/7206700.html

你可能感兴趣的文章
JAVA常见工具配置
查看>>
Cannot find snapshot in models/VGGNet/VOC0712/SSD_300x300
查看>>
深入理解jQuery插件开发【转】
查看>>
0 - python简介
查看>>
第20章 使用LNMP架构部署动态网站环境
查看>>
meson 中调用shell script
查看>>
相关博客
查看>>
Servlet运行原理以及生命周期
查看>>
Linux学习之三-Linux系统的一些重要配置文件
查看>>
转 [JAVA] 使用 common-fileupload 实现文件上传
查看>>
十五天精通WCF——第三天 client如何知道server提供的功能清单
查看>>
构建之法阅读笔记04
查看>>
Python - selenium_WebDriver 鼠标键盘事件
查看>>
oracle创建DBLink连接
查看>>
spark+openfire即时通讯工具二次开发参考文档
查看>>
java.util.concurrent包API学习笔记
查看>>
从技术细节看美团的架构
查看>>
Odoo进销存业务学习笔记
查看>>
c++标准库 及 命名空间std
查看>>
【POJ1113】Wall(凸包)
查看>>