ChartCtrl源码剖析之——CChartTitle类

CChartTitle类顾名思义,该类用来绘制波形控件的标题,它处于该控件的区域,如下图所示: 

CChartTitle类的头文件。

#if !defined(AFX_CHARTTITLE_H__49972787_6D28_4F81_A12F_420947456913__INCLUDED_)
#define AFX_CHARTTITLE_H__49972787_6D28_4F81_A12F_420947456913__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "ChartObject.h"
#include <vector>
#include "ChartString.h"
class CChartTitle : public CChartObject  
{
    friend CChartCtrl;
public:
    size_t GetStringCount() const;
    TChartString GetString(size_t Index) const;
    void AddString(const TChartString& NewString);
    void RemoveAll();
    void SetFont(int iPointSize, const TChartString& strFaceName);
    CChartTitle(CChartCtrl* pParent);
    virtual ~CChartTitle();
private:
    CSize GetSize(CDC* pDC);
    void Draw(CDC *pDC);
    std::vector<TChartString> m_StringArray;
    TChartString m_strFontName;
    int          m_iFontSize;
};
#endif // !defined(AFX_CHARTTITLE_H__49972787_6D28_4F81_A12F_420947456913__INCLUDED_)

其中,ChartString.h头文件。 

#pragma once
#include <string>
#if defined _UNICODE || defined UNICODE
    typedef std::wstring TChartString;
#else
    typedef std::string TChartString;
#endif

CChartTitle类的源文件。

#include "stdafx.h"
#include "ChartTitle.h"
#include "ChartCtrl.h"
#include "Math.h"
using namespace std;
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CChartTitle::CChartTitle(CChartCtrl* pParent) : CChartObject(pParent)
{
    m_ObjectColor = RGB(0,0,0);
    m_iFontSize = 100;
    m_strFontName = _T("Microsoft Sans Serif");
}
CChartTitle::~CChartTitle()
{
}
void CChartTitle::SetFont(int iPointSize, const TChartString& strFaceName)
{
    m_iFontSize = iPointSize;
    m_strFontName = strFaceName;
    m_pParent->RefreshCtrl();
}
void CChartTitle::AddString(const TChartString& NewString)
{
    m_StringArray.push_back(NewString);
    m_pParent->RefreshCtrl();
}
size_t CChartTitle::GetStringCount() const
{
    return m_StringArray.size();
}
TChartString CChartTitle::GetString(size_t Index) const
{
    if ( (Index<0) || (Index>=m_StringArray.size()) )
        return _T("");
    return m_StringArray[Index];
}
void CChartTitle::RemoveAll()
{
    m_StringArray.clear();
    m_pParent->RefreshCtrl();
}
void CChartTitle::Draw(CDC *pDC)
{
    if (!pDC->GetSafeHdc())
        return;
    if (!m_bIsVisible)
        return;
    CFont* pOldFont;
    CFont NewFont;
    NewFont.CreatePointFont(m_iFontSize,m_strFontName.c_str(),pDC);
    COLORREF OldColor = pDC->SetTextColor(m_ObjectColor);
    pOldFont = pDC->SelectObject(&NewFont);
    int iPrevMode = pDC->SetBkMode(TRANSPARENT);
    //Draw all entries
    int YPos = 4;
    size_t TitleCount = m_StringArray.size();
    for (size_t i=0;i<TitleCount;i++)
    {
        //Draw Text
        int TextWidth = pDC->GetTextExtent(m_StringArray[i].c_str()).cx;
        int TextHeigh = pDC->GetTextExtent(m_StringArray[i].c_str()).cy;
        int XPos = m_ObjectRect.left + (int)fabs((m_ObjectRect.left-m_ObjectRect.right)/2.0) - TextWidth/2;
        if (m_bShadow)
        {
            pDC->SetTextColor(m_ShadowColor);
            pDC->ExtTextOut(XPos+m_iShadowDepth,m_ObjectRect.top+YPos+m_iShadowDepth,
                            ETO_CLIPPED,NULL,m_StringArray[i].c_str(),NULL);
            pDC->SetTextColor(m_ObjectColor);
        }
        pDC->ExtTextOut(XPos,m_ObjectRect.top+YPos,ETO_CLIPPED,NULL,m_StringArray[i].c_str(),NULL);
        YPos += TextHeigh + 2;
    }
    pDC->SelectObject(pOldFont);
    DeleteObject(NewFont);
    pDC->SetTextColor(OldColor);
    pDC->SetBkMode(iPrevMode);
}
CSize CChartTitle::GetSize(CDC *pDC)
{
    CSize TitleSize;
    if (!m_bIsVisible)
    {
        TitleSize.cx = TitleSize.cy = 0;
        return TitleSize;
    }
    int Height = 4;        //Upper space
    CSize TextSize = 0;
    int MaxTextWidth = 0;
    size_t TitleCount = m_StringArray.size();
    if (TitleCount==0)
    {
        TitleSize.cx = TitleSize.cy = 0;
        return TitleSize;
    }
    CFont* pOldFont;
    CFont NewFont;
    NewFont.CreatePointFont(m_iFontSize,m_strFontName.c_str(),pDC);
    pOldFont = pDC->SelectObject(&NewFont);
    for (size_t i=0;i<TitleCount;i++)
    {
        TextSize = pDC->GetTextExtent(m_StringArray[i].c_str());
        Height += TextSize.cy + 2;
        if (TextSize.cx > MaxTextWidth)
            MaxTextWidth = TextSize.cx;
    }
    TitleSize.cx = MaxTextWidth + 2;
    TitleSize.cy = Height;
    m_ObjectRect.bottom = m_ObjectRect.top + Height;
    pDC->SelectObject(pOldFont);
    DeleteObject(NewFont);
    return TitleSize;
}

GetSize函数用来获取标题文字的长度和宽度,Draw函数用来在指定位置绘制标题文字。在初次阅读这份源码的时候在如何确定m_ObjectRect大小的时候纠结了很长时间,现在读的时候感觉无比顺畅,真是应了那句古话,书读百遍其义自现,代码读个三五遍,一开始读不懂的统统全部拿下,感觉特别Happy。 

作者:常想一二
出处:http://www.cnblogs.com/wolfmvp/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。
原文地址:https://www.cnblogs.com/wolfmvp/p/7206197.html