duilib-自定义曲线控件
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-自定义曲线控件相关推荐
- android自定义曲线控件,Android自定义view进阶-- 神奇的贝塞尔曲线
上一篇介绍了自定义view需要知道的基本函数.新开一篇献给借给我vpn的深圳_奋斗小哥. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/ ...
- android自定义曲线控件,Android自定义折线图(可拖动显示)
废话不多说先上图咯 图一 至于怎么做呢 咱们可以先获取下折线图数据分析一波 { "code": 200, "message": "", &q ...
- Android 手机卫士--自定义组合控件构件布局结构
由于设置中心条目中的布局都很类似,所以可以考虑使用自定义组合控件来简化实现 本文地址:http://www.cnblogs.com/wuyudong/p/5909043.html,转载请注明源地址. ...
- 转帖 .Net(C#)纯GDI+绘制实时动态曲线图之二(曲线控件全部源码)
#region 曲线数据显示 #region 绘制背景网格 /// <summary> /// 刷新背景网格线,并返回背景图片(背景不判断是否滚动) /// </s ...
- Android View体系(十)自定义组合控件
相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...
- iOS自定义View 控件自动计算size能力
iOS自定义View 控件自动计算size能力 背景 在使用 UILabel 和 UIImage 的时候,不用指定宽高约束,控件也不会报约束缺失,还可以根据内容自己确定适合的宽高,特别适合 Xib 和 ...
- VS2010 自定义用户控件未出现在工具箱的解决方案
VS2010 自定义用户控件未出现在工具箱的解决方案 参考文章: (1)VS2010 自定义用户控件未出现在工具箱的解决方案 (2)https://www.cnblogs.com/lyout/arch ...
- [置顶] 分步实现具有分页功能的自定义DataList控件【附源代码】
一.控件也是类 [效果] [操作步骤] 1. 新建网站Web 2. 添加类CustomDataList.cs(系统会提示你把类建在App_Code文件夹中),代码如下: using System; ...
- [转] 使用模板自定义 WPF 控件
[转] 使用模板自定义 WPF 控件 ...
最新文章
- 三大平衡树(Treap + Splay + SBT)总结+模板
- 虚拟机安装linux系统无法上网的解决方法
- 2020南大计科考研实记(受难三跨)
- 3步理清Python数据分析关键点,新手必看
- 获取当前Tomcat实例的端口
- 行列式、LGV、矩阵树学习笔记
- 后台系统可扩展性学习笔记(七)Service Discovery与微服务
- Leetcode 335. 路径交叉(Self Crossing)
- 轩辕炼妖录java_一个Java对象的回忆录:那些被锁住的日子
- Java定义一维数组从键盘赋值
- dill:解决python的“AttributeError: Can‘t pickle local object”及无法pickle lambda函数的问题
- python零基础能学吗-初学者必知:零基础学习Python真的能学会吗?
- c语言 头文件卫士详解,C 语言条件编译与防止头文件重复
- ubuntu 安装 teamViewer 出现错误
- Padavan启用ipv6并允许公网访问内网
- 线性丢番图方程的C++实现
- 推出 BlazePose:实现设备端实时人体姿态追踪
- 模型prun quantization related paper
- 我如何从月薪8K到25K?现在分享给大家自己的经历
- 时间工具类、Instant、date、LocalDate、String、LocalDateTime 相互转换