duilib-自定义曲线控件

duilib现有的控件继承图如下:


从上图可以看出常见的控件都是由CControlUI继承而来,因此如果需要自定义控件,可以继承CControlUI,重写子类。如何做一个类似windows任务管理器的曲线控件,如下图所示:

自定义曲线控件展示如下:

下面详细说明如何在duilib源码中自定义曲线控件,以及如何在xml中设置控件属性。

1、重写控件类CChartCtrlUI,继承于CLabelUI或者CControlUI,控件类CChartCtrlUI中必须重写的函数方法如下:

LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
void DoEvent(TEventUI& event);
void DoPaint(HDC hDC, const RECT& rcPaint);
void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

GetClass()返回自定义的控件name属性值

LPCTSTR CChartCtrlUI::GetClass() const
{return DUI_CTR_CHART_CONTROL;
}

GetInterface()返回控件指针

LPVOID CChartCtrlUI::GetInterface(LPCTSTR pstrName)
{if (_tcscmp(pstrName, DUI_CTR_CHART_CONTROL) == 0) return static_cast<CChartCtrlUI*>(this);return CControlUI::GetInterface(pstrName);
}

DoEvent()重写控件响应,包括鼠标键盘的动作,触发后发送UI主线程通知消息,如果需要捕获消息请重写DoEvent.

void CChartCtrlUI::DoEvent(TEventUI& event)
{CControlUI::DoEvent(event);
}

DoPaint()控件界面重绘,可以在此函数内绘制图像,曲线等等,如何使用gdi+绘制曲线,画图等,可以参考网上资料。

void CChartCtrlUI::DoPaint(HDC hDC, const RECT& rcPaint)
{CControlUI::DoPaint(hDC, rcPaint);m_rectChart = this->GetPos();//重绘制曲线图{Pen      pen(m_curvPenColor);Graphics graphics(hDC);graphics.SetSmoothingMode(SmoothingModeAntiAlias);Status restatus = graphics.DrawCurve(&pen, (const PointF*)m_stPointXy, m_nCurPointCount);m_bDataAdd = false;}}

SetAttribute()解析界面xml文件中控件自定义属性值,如何解析可以参考CLabelUI或CControlUI类中的SetAttribute函数,例如自定义了curvpen,曲线画笔颜色,截取控件宽度值,设置曲线绘制点数总和,方便平移操作。

void CChartCtrlUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{LPTSTR pstr = NULL;if (_tcscmp(pstrName, _T("curvpen")) == 0) {if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);LPTSTR pstr = NULL;DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);SetCurvPenColor(clrColor);}else if (_tcscmp(pstrName, _T("width")) == 0){DWORD dwWidth = _tcstoul(pstrValue, &pstr, 10);int nWidth;nWidth = dwWidth;ASSERT(nWidth > 0);m_stPointXy = new PointF[nWidth];ASSERT(m_stPointXy != NULL);CControlUI::SetAttribute(pstrName, pstrValue);}elseCControlUI::SetAttribute(pstrName, pstrValue);
}

2、在UIDefine.h中添加控件类名的宏定义。

#define  DUI_CTR_CHART_CONTROL                   (_T("ChartControl"))

3、在UIDlgBuilder.cpp的_paser函数中增加控件的创建代码,根据类名的长度为12,写在case 12下:

         case 12:if (_tcscmp(pstrClass, DUI_CTR_CHART_CONTROL) == 0)             pControl = new CChartCtrlUI;break;

4、在UIlib.h中包含头文件

#include "Control/UIChartCtrl.h"

5、使用xml编写

<ChartControl name="cpuChart" text=" " textcolor="#FFFF0000" height="40" width="160" bordersize="1" bordercolor="#FF1E90FF" curvpen="#FF1E90FF" />

6、头文件与源文件如下

//UIChartCtrl.h

#ifndef UI_CHART_CTRL_H
#define UI_CHART_CTRL_H
#pragma once#include <GdiPlus.h>
#pragma comment( lib, "GdiPlus.lib" )
using namespace Gdiplus;
class UILIB_API Gdiplus::RectF;
struct UILIB_API Gdiplus::GdiplusStartupInput;namespace DuiLib
{class UILIB_API CChartCtrlUI : public CLabelUI{public:CChartCtrlUI();~CChartCtrlUI();LPCTSTR GetClass() const;LPVOID GetInterface(LPCTSTR pstrName);void       SetEnabledEffect(bool _EnabledEffect);bool      GetEnabledEffect();void SetText(LPCTSTR pstrText);CDuiString    GetText() const;void DoEvent(TEventUI& event);void DoPaint(HDC hDC, const RECT& rcPaint);void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);void SetCurvPenColor(DWORD dwColor);void InitCtrl(); //初始化数据,分配数据空间int GetPointCount();void AddPointXy(PointF clsPointF);PointF valueToPointF(float value);private:DWORD                 m_curvPenColor; //绘制曲线画笔PointF                  * m_stPointXy;//显示100个值,超过就后移int                     m_nCurPointCount;bool                   m_EnableEffect;CDuiString               m_TextValue;ULONG_PTR               m_gdiplusToken;GdiplusStartupInput      m_gdiplusStartupInput;bool                    m_bDataAdd; //是否有数据加入,加入则重绘bool                    m_bFirstUpdate;  //是否界面更新一次RECT                 m_rectChart;  //窗口相对于客户区的坐标};
}
#endif

//UIChartCtrl.cpp

#include "StdAfx.h"
#include "UIChartCtrl.h"#include <atlconv.h>
namespace DuiLib
{CChartCtrlUI::CChartCtrlUI() : m_gdiplusToken(0),m_EnableEffect(false),m_stPointXy(NULL),m_bDataAdd(false),m_bFirstUpdate(false){m_nCurPointCount = 0;GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);}CChartCtrlUI::~CChartCtrlUI(){try{GdiplusShutdown(m_gdiplusToken);if (m_stPointXy != NULL){delete m_stPointXy;m_stPointXy = NULL;}}catch (...){throw "CChartCtrlUI::~CChartCtrlUI";}}LPCTSTR CChartCtrlUI::GetClass() const{return DUI_CTR_CHART_CONTROL;}LPVOID CChartCtrlUI::GetInterface(LPCTSTR pstrName){if (_tcscmp(pstrName, DUI_CTR_CHART_CONTROL) == 0) return static_cast<CChartCtrlUI*>(this);return CControlUI::GetInterface(pstrName);}CDuiString CChartCtrlUI::GetText() const{try{if (!m_EnableEffect)return CControlUI::GetText();return m_TextValue;}catch (...){throw "CChartCtrlUI::GetText";}}void CChartCtrlUI::SetText(LPCTSTR pstrText){try{if (!GetEnabledEffect())return CControlUI::SetText(pstrText);m_TextValue = pstrText;}catch (...){throw "CChartCtrlUI::SetText";}}void CChartCtrlUI::SetEnabledEffect(bool _EnabledEffect){try{m_EnableEffect = _EnabledEffect;}catch (...){throw "CLabelUI::SetEnabledEffect";}}bool CChartCtrlUI::GetEnabledEffect(){try{return m_EnableEffect;}catch (...){throw "CLabelUI::GetEnabledEffect";}}void CChartCtrlUI::DoEvent(TEventUI& event){CControlUI::DoEvent(event);}void CChartCtrlUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue){LPTSTR pstr = NULL;if (_tcscmp(pstrName, _T("curvpen")) == 0) {if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);LPTSTR pstr = NULL;DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);SetCurvPenColor(clrColor);}else if (_tcscmp(pstrName, _T("width")) == 0){DWORD dwWidth = _tcstoul(pstrValue, &pstr, 10);int nWidth;nWidth = dwWidth;ASSERT(nWidth > 0);m_stPointXy = new PointF[nWidth];ASSERT(m_stPointXy != NULL);CControlUI::SetAttribute(pstrName, pstrValue);}elseCControlUI::SetAttribute(pstrName, pstrValue);}void CChartCtrlUI::SetCurvPenColor(DWORD dwColor){m_curvPenColor = dwColor;}int CChartCtrlUI::GetPointCount(){return m_nCurPointCount;}void CChartCtrlUI::InitCtrl(){//int width = this->GetWidth();//ASSERT(width > 0);//m_stPointXy = new PointF[width];//ASSERT(m_stPointXy != NULL);int width;m_rectChart = this->GetPos();width = m_rectChart.right - m_rectChart.left;ASSERT(width > 0);m_stPointXy = new PointF[width];ASSERT(m_stPointXy != NULL);}void CChartCtrlUI::AddPointXy(PointF clsPointF){POINTF tempPf;if (m_nCurPointCount > this->GetWidth())return;if (m_nCurPointCount == this->GetWidth()){for (int i = 0; i < m_nCurPointCount-1; i++){m_stPointXy[i].Y = m_stPointXy[i+1].Y;//X值保持不变}m_stPointXy[m_nCurPointCount-1] = clsPointF;}else{m_stPointXy[m_nCurPointCount].X = clsPointF.X;m_stPointXy[m_nCurPointCount].Y = clsPointF.Y;m_nCurPointCount++;}m_bDataAdd = true;}PointF CChartCtrlUI::valueToPointF(float value){PointF clsRes;int height, width;height = this->GetHeight();width = this->GetWidth();ASSERT(height > 0);ASSERT(width > 0);clsRes.Y = m_rectChart.top + (height - value / 100.0 * height);if (m_nCurPointCount < width)clsRes.X = m_nCurPointCount + 1 + m_rectChart.left;elseclsRes.X = m_nCurPointCount + m_rectChart.left;return clsRes;}void CChartCtrlUI::DoPaint(HDC hDC, const RECT& rcPaint){CControlUI::DoPaint(hDC, rcPaint);m_rectChart = this->GetPos();//重绘制曲线图//if (m_bDataAdd) //有数据加入{Pen      pen(m_curvPenColor);Graphics graphics(hDC);graphics.SetSmoothingMode(SmoothingModeAntiAlias);Status restatus = graphics.DrawCurve(&pen, (const PointF*)m_stPointXy, m_nCurPointCount);m_bDataAdd = false;}}
}

duilib-自定义曲线控件相关推荐

  1. android自定义曲线控件,Android自定义view进阶-- 神奇的贝塞尔曲线

    上一篇介绍了自定义view需要知道的基本函数.新开一篇献给借给我vpn的深圳_奋斗小哥. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/ ...

  2. android自定义曲线控件,Android自定义折线图(可拖动显示)

    废话不多说先上图咯 图一 至于怎么做呢 咱们可以先获取下折线图数据分析一波 { "code": 200, "message": "", &q ...

  3. Android 手机卫士--自定义组合控件构件布局结构

    由于设置中心条目中的布局都很类似,所以可以考虑使用自定义组合控件来简化实现 本文地址:http://www.cnblogs.com/wuyudong/p/5909043.html,转载请注明源地址. ...

  4. 转帖 .Net(C#)纯GDI+绘制实时动态曲线图之二(曲线控件全部源码)

    #region 曲线数据显示 #region 绘制背景网格    /// <summary>    /// 刷新背景网格线,并返回背景图片(背景不判断是否滚动)    /// </s ...

  5. Android View体系(十)自定义组合控件

    相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...

  6. iOS自定义View 控件自动计算size能力

    iOS自定义View 控件自动计算size能力 背景 在使用 UILabel 和 UIImage 的时候,不用指定宽高约束,控件也不会报约束缺失,还可以根据内容自己确定适合的宽高,特别适合 Xib 和 ...

  7. VS2010 自定义用户控件未出现在工具箱的解决方案

    VS2010 自定义用户控件未出现在工具箱的解决方案 参考文章: (1)VS2010 自定义用户控件未出现在工具箱的解决方案 (2)https://www.cnblogs.com/lyout/arch ...

  8. [置顶] 分步实现具有分页功能的自定义DataList控件【附源代码】

    一.控件也是类 [效果] [操作步骤] 1.  新建网站Web 2.  添加类CustomDataList.cs(系统会提示你把类建在App_Code文件夹中),代码如下: using System; ...

  9. [转] 使用模板自定义 WPF 控件

      [转] 使用模板自定义 WPF 控件                                                                                 ...

最新文章

  1. 三大平衡树(Treap + Splay + SBT)总结+模板
  2. 虚拟机安装linux系统无法上网的解决方法
  3. 2020南大计科考研实记(受难三跨)
  4. 3步理清Python数据分析关键点,新手必看
  5. 获取当前Tomcat实例的端口
  6. 行列式、LGV、矩阵树学习笔记
  7. 后台系统可扩展性学习笔记(七)Service Discovery与微服务
  8. Leetcode 335. 路径交叉(Self Crossing)
  9. 轩辕炼妖录java_一个Java对象的回忆录:那些被锁住的日子
  10. Java定义一维数组从键盘赋值
  11. dill:解决python的“AttributeError: Can‘t pickle local object”及无法pickle lambda函数的问题
  12. python零基础能学吗-初学者必知:零基础学习Python真的能学会吗?
  13. c语言 头文件卫士详解,C 语言条件编译与防止头文件重复
  14. ubuntu 安装 teamViewer 出现错误
  15. Padavan启用ipv6并允许公网访问内网
  16. 线性丢番图方程的C++实现
  17. 推出 BlazePose:实现设备端实时人体姿态追踪
  18. 模型prun quantization related paper
  19. 我如何从月薪8K到25K?现在分享给大家自己的经历
  20. 时间工具类、Instant、date、LocalDate、String、LocalDateTime 相互转换

热门文章

  1. k8s之PV以及PVC
  2. pagehelper浅见
  3. Swagelok SS-62TF4-31C-GC
  4. Polymesh 公司行为 发放股息
  5. 封基高折价 投资机会扩大
  6. 增值税发票识别(调研ing)
  7. 关于 MATLAB 你首先要会的基础(权且可当做期末复习备考)
  8. 【论文相关】论文管理神器-zotero(最详细的使用说明)
  9. zoj 1010 Area【线段相交问题】
  10. 2023年上海大学文物与博物馆考研上岸前辈初复试备考经验指导