| 上位机MFC扩展编程图表图例添加单选复选框及自定义内容 
 前面实例介绍图表中图例元素的管理,元素如标题,网格等都是自带的。
 这个实例实现在图例中添加自定义的内容,实现添加自定义三行内容,
 第一行为单列,第二行为三列,第三行为三列,列为单选框与复选框控件。
 效果如下图:
 
   
 例程是在前面例程基础上创建,所以会带有几个图例元素操作按钮。
 例程实现的是在图例上添加自定义内容,如图例尾部添加的三行自定义控件。
 其中最后一行带有单选框与两个复选框。
 点击单选框或复选框会触发消息,弹出对话框。
 
 这里例程的关键点为:
 图例成功创建后会发送消息BCGM_ON_CHART_LEGEND_CONTENT_CREATED。
 所以我们可以关联消息处理函数,在函数内向图例添加自定义内容。
 ON_REGISTERED_MESSAGE(BCGM_ON_CHART_LEGEND_CONTENT_CREATED, OnLegendContentCreated)
 
 由于单选框,复选框要处理自绘功能与鼠标选择等事件,所以例程创建了两个集成类来管理,还有一个类为父类。
 控件选择事件通过定义用户消息来发送。
 
 这样我们要处理单选框,复选框选择消息,就可以关联两消息UM_CHECKCLICKED,UM_RADIOCLICKED处理函数。复制代码
CMy123View* g_View = NULL;
#define UM_CHECKCLICKED WM_USER+1
#define UM_RADIOCLICKED WM_USER+2
class CChartLegendControl : public CBCGPChartLegendCell
{
protected:
        BOOL                                                m_bIsSelected;
public:
        DECLARE_DYNAMIC(CChartLegendControl);
        CChartLegendControl(const CString& strName,BOOL bChecked) :
        CBCGPChartLegendCell(strName)
        {
                m_bIsSelected = bChecked;
        }
        void SetSelected(BOOL bSet)
        {
                m_bIsSelected = bSet;
                Redraw();
        }
        void SetSelected()
        {
                m_bIsSelected = !m_bIsSelected;
                Redraw();
        }
        BOOL IsSelected() const
        {
                return m_bIsSelected;
        }
        virtual CBCGPSize OnCalcCustomCellSize(CBCGPGraphicsManager* pGM)
        {
                CBCGPSize size = CBCGPChartLegendCell::OnCalcCustomCellSize(pGM);
                size.cy += 4;
                size.cx += size.cy + size.cy / 4.0;
                return size;
        }
        virtual void OnDrawCheckRadio(CBCGPGraphicsManager* pGM, const CBCGPRect& rect, const CBCGPColor& color) = 0;
        //由库调用,控件自绘;
        virtual void OnDrawCustomCell(CBCGPGraphicsManager* pGM, const CBCGPRect& rect)
        {
                CBCGPRect rectCheck = rect;
                rectCheck.right = rectCheck.left + rectCheck.Height();
                CBCGPRect rectLabel = rect;
                rectLabel.left = rectCheck.right + rectCheck.Height() / 4.0;
                rectCheck.DeflateRect(2, 2);
                OnDrawCheckRadio(pGM, rectCheck, m_cellParams.m_brTextColor.GetColor());
                CBCGPChartLegendCell::OnDrawCustomCell(pGM, rectLabel);
        }
};
class CChartLegendCheckBox : public CChartLegendControl
{
public:
        DECLARE_DYNAMIC(CChartLegendCheckBox);
        CChartLegendCheckBox(const CString& strName,BOOL bChecked=FALSE) :
        CChartLegendControl(strName,bChecked)
        {
        }
        virtual void OnMouseUp(const CBCGPPoint& pt)
        {
                CBCGPChartLegendCell::OnMouseUp(pt);
                if(this->IsSelected())
                        return;
                SetSelected();
                PostMessage(g_View->m_hWnd,UM_CHECKCLICKED,(WPARAM)0,(LPARAM)IsSelected() );
        }
        //绘制单选框;
        virtual void OnDrawCheckRadio(CBCGPGraphicsManager* pGM, const CBCGPRect& rect, const CBCGPColor& color)
        {
                pGM->DrawCheckBox(rect, m_bIsSelected, color);
        }
};
class CChartLegendRadioButton : public CChartLegendControl
{
public:
        DECLARE_DYNAMIC(CChartLegendRadioButton);
        CChartLegendRadioButton(const CString& strName,BOOL bChecked=TRUE) :
        CChartLegendControl(strName,bChecked)
        {
        }
        virtual void OnMouseUp(const CBCGPPoint& pt)
        {
                CBCGPChartLegendCell::OnMouseUp(pt);
                if(this->IsSelected())
                        return;
                CBCGPChartLegendVisualObject* pLegend = this->GetParentLegend();
                int nCheckedIndex=0;
                int nCount = pLegend->GetLegendEntryCount();
                for(int i=0; i<nCount; i++)
                {
                        CBCGPChartLegendEntry* pEntry = pLegend->GetLegendEntry(i);
                        int n=pEntry->GetCellCount();
                        for(int y=0; y<n; y++)
                        {
                                CChartLegendRadioButton* pRadio = DYNAMIC_DOWNCAST(CChartLegendRadioButton,pEntry->GetCell(y));
                if(pRadio != NULL)
                                {
                                        pRadio->SetSelected(FALSE);
                                        if(pRadio == this)
                                                nCheckedIndex = y-1;//实例中添加有1单选框,所以这里减1;
                                }
                        }
                }
                this->SetSelected(TRUE);
                PostMessage(g_View->m_hWnd,UM_RADIOCLICKED,(WPARAM)0,(LPARAM)nCheckedIndex);                
        }
        virtual void OnDrawCheckRadio(CBCGPGraphicsManager* pGM, const CBCGPRect& rect, const CBCGPColor& color)
        {
                pGM->DrawRadioButton(rect, m_bIsSelected, color);
        }
};
IMPLEMENT_DYNAMIC(CChartLegendControl, CBCGPChartLegendCell)
IMPLEMENT_DYNAMIC(CChartLegendCheckBox, CChartLegendControl)
IMPLEMENT_DYNAMIC(CChartLegendRadioButton, CChartLegendControl)
另外这两消息是向视窗类发送,所以例程还定义了视窗类的全局变量CMy123View* g_View = NULL;
 记得初始化它。
 
 准备好后,就可以处理消息BCGM_ON_CHART_LEGEND_CONTENT_CREATED关联的函数OnLegendContentCreated了。
 
 例程中关于图表的创建可以参考前面帖子介绍。复制代码//图例创建或内容更新后发送消息BCGM_ON_CHART_LEGEND_CONTENT_CREATED;
//更新时要重新创建内容,所以下面要重新NEW;
LRESULT CMy123View::OnLegendContentCreated(WPARAM, LPARAM lp)
{
        CBCGPChartLegendVisualObject* pLegend = (CBCGPChartLegendVisualObject*)lp;
        ASSERT_VALID(pLegend);
        BCGPChartCellParams params;
        params.m_brContentFill = CBCGPBrush(CBCGPColor::LightSalmon, CBCGPColor::Wheat, CBCGPBrush::BCGP_GRADIENT_PIPE_HORIZONTAL);
        params.m_brTextColor   = CBCGPBrush(CBCGPColor::DarkRed);;
        params.SetContentPadding(CBCGPSize(10.0, 2.0));
        // 添加自定义行1;
        CBCGPChartLegendEntry* pEntry = new CBCGPChartLegendEntry(m_pLegend);
        CBCGPChartLegendCell* pCell = new CBCGPChartLegendCell(_T("自定义行1"));
        pCell->SetCellParams(params);
        pEntry->AddLegendCell(pCell);
        pLegend->InsertLegendEntry(pEntry, pLegend->GetLegendEntryCount());
        // 添加自定义行2;
        pEntry = new CBCGPChartLegendEntry(m_pLegend);
        pEntry->AddLegendCell(new CBCGPChartLegendCell(_T("自定义行2")));
        pEntry->AddLegendCell(new CBCGPChartLegendCell(_T("行2列1")));
        pEntry->AddLegendCell(new CBCGPChartLegendCell(_T("行2列2")));
        pLegend->AddLegendEntry(pEntry);
        // 添加自定义行3;
        pEntry = new CBCGPChartLegendEntry(m_pLegend);
        pEntry->AddLegendCell(new CChartLegendCheckBox(_T("单选框")));
        pEntry->AddLegendCell(new CChartLegendRadioButton(_T("复选框1"),TRUE));
        pEntry->AddLegendCell(new CChartLegendRadioButton(_T("复选框2"),FALSE));
        pLegend->AddLegendEntry(pEntry);
        return 0;
}
例程中使用到的扩展库,可以搜索BCGP下载使用。
 例程源代码下载:
 
 
   如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!    
 
 
 
 |