文章目录

  • 简介
    • 效果图
    • 现状分析
    • DDUI控件全景图
  • 设计原理
    • Delphi中的UI设计
    • 区分“设计时”和“运行时”
    • GDI VS GDI+
    • 消息分发
    • 皮肤
    • TDUIWinBase
      • 容器类
      • 控件类
      • Scintilla
  • 后续工作
  • 联系作者

简介

ETS_DDUI是一套Delphi原生的DUI控件,完全兼容于VCL,开发这套控件的目的是为了改善Delphi程序的界面显示效果。

开源地址

效果图

Demo程序借鉴了360的设计。

此页面是对目前已支持的DUI控件的测试样例。

此页面是表格控件的测试样例。

此页面中展示的控件并不是DUI控件,而是Delphi的常规控件,用于演示如何将常规控件用到DUI的框架中。
右侧用到的编辑器是开源的Scintilla,需要自行编译出DLL文件,放到Demo二进制程序的同级目录中,更简单的方式是下载最新的Notepad++,然后,拷贝其中的SciLexer.dll文件即可。

现状分析

在网上搜了下,还真找到几个不错的开源DUI控件库,主要以C++的居多,Delphi的有一个,但核心还是基于C++的版本。

  • DuiLib: 这是我很久以前就听说过的版本,最初好像是一个丹麦的大神写的一个Demo,之后DuiLib的作者以其为基础做了完善,据说很多大厂的产品中都用到过这个库,但可惜作者已经弃坑了,源码地址。
  • DDuilib: 这是我在网上找到的唯一一个Delphi的DUI库,本质上只是对DuiLib的二次包装,核心还是基于C++,源码地址。
  • DuiVision: 看起来很强大的一个库,也是C++写的,源码地址。

和这些开源库相比,感觉ETS_DDUI要走的路还很长,目前实现了一个基本框架和一些基础控件,算是在Delphi中开发DUI界面的另一个选择吧。

DDUI控件全景图

设计原理

Delphi中的UI设计

其实,从Delphi本身而言,是支持DUI控件的,我们先来看看VCL的类继承体系。

Delphi中的控件可以分为三大类:

  • 从TComponent直接继承,这类控件不带有界面外观,常见的如数据库相关控件。
  • 从TControl直接继承,这类控件实际上就是DUI控件,控件不会创建窗口句柄。
  • 从TWinControl继承,这类控件就是最常见的带窗口句柄的控件,后文我会将这类控件叫做GUI控件

如果我们引入一套新的控件,直接从TControl继承,那么,这些控件就天然是DUI控件了。
但Delphi在设计上有个很大的限制,那就是Parent这个属性,被定义为TWinControl类型。
也就是说,DUI控件只能放在GUI控件之上,DUI控件本身不能叠加摆放。
这样一来,在功能设计时,程序模块化不太好做。

例如,如下图所示:

我们将窗口划分为两个区域,上边是功能选择区,下边是功能显示区。
由于不同的功能,显示区要展示的内容都不同,因此,我一般会把显示区提取出来,单独用TFrame实现。
当选择不同的功能时,就把不同的TFrame贴到显示区中。
但因为前面说到的Delphi的限制,TFrame就必须是TWinControl控件,这样一来,就无法完全做到无窗口句柄的效果。

区分“设计时”和“运行时”

ETS_DDUI解决这个问题的办法是区分设计时和运行时。
ETS_DDUI构建完成后,会生成两个bpl文件:dclDDUI.bplDDUI.bpl
两个bpl共用同一套代码,但前者从TWinControl继承,后者从TControl继承。
在Delphi IDE环境中,我们安装dclDDUI.bpl,但在我们自己的程序中,我们链接DDUI.bpl。
这样一来,在Delphi IDE中,创建的控件实际上都是GUI控件,我们就能享受到Delphi窗口设计器所带来的诸多好处。
而在运行时,创建的是DUI控件,这样就能实现无句柄的效果。

GDI VS GDI+

Delphi中的绘图类是TCanvas,其本身是对Windows的GDI API做的包装。
但GDI对颜色的Alpha通道支持得非常有限,所以,在实现半透明、颜色渐变等效果时,会比较麻烦。
所以,ETS_DDUI在设计时,直接抛弃了TCanvas,改为使用GDI+。

消息分发

DUI和GUI的最大区别,本人认为就是在消息分发上。
GUI由于具有窗口句柄,因此,控件本身会自动产生各类消息。
DUI由于是模拟出来的,因此,消息全部由最底层的主窗口产生,然后一层层的往上分发。

常见的消息可分为三类:

  • 绘图消息(WM_Paint),处理时,由主窗口最先绘制,然后,上层的DUI控件再一层层的按叠放顺序绘制。
  • 鼠标消息(WM_MOUSEFIRST~WM_MOUSELAST),和绘图消息的处理顺序刚好相反,先将消息分发到上层控件处理,如果上层控件不处理,下层控件才处理。
  • 键盘消息(WM_KEYFIRST~WM_KEYLAST),主窗口要跟踪记录获取焦点的控件,处理时,直接将消息分发到焦点控件。

皮肤

很多使用DUI控件开发的程序,都有类似换肤的功能,所以,在DUI控件中引入对皮肤的支持,还是有必要的。
皮肤的实现,简单点说,就是将颜色、画刷、图片等绘图要素,统一放到一起管理。
每个绘图要素都有一个唯一的名称,DUI控件在绘制界面时,通过名称取用。

ETS_DDUI将绘图要素分为五个大类进行管理:TDUIBrush、TDUIColor、TDUIFont、TDUIPen、TDUIPicture。
相关的配置信息放在"Skin.json"文件中保存,加载时,通过RTTI机制,从json文件中读取属性,创建相应的绘图要素的对象实例。
换肤的功能,实际上就是切换json文件后,重新加载的过程。

TDUIWinBase

Delphi中存在大量的TWinControl控件,如果弃之不用,着实可惜。
但TWinControl无法直接放到DUI控件上使用,因为DUI控件没有窗口句柄,无法设置为父窗口。
因此,引入了TDUIWinBase基类,其对TWinControl重新做了层包装,使其可以当成DUI控件使用。
根据Delphi控件的不同特性,可分为容器类和控件类这两套分支体系。

容器类

容器类仅提供了一个实现TDUIWinContainer
本质上只是对TFrame的包装,这样,就可以直接在上面放置TWinControl、TControl等常规控件。

由于TFrame不会自绘背景,目前代码中包装的是自定义的控件,但实现上参考了TFrame的实现。

控件类

目前仅实现了一个TDUIEdit,对TEdit做的包装,提供简单文本的输入功能。

Scintilla

Scintilla并不属于ETS_DDUI控件集的范畴,只不过因为其功能比较强大,因此,才引入进来。
可能很多同学并没听说过这个控件,但Notepad++相信不少人听说过吧,而Notepad++底层就是用的Scintilla,是其最核心的文本编辑器。
而ETS_DDUI也对这个控件做了一层简单包装(TScintilla),作为TRichEdit的替代品使用。

后续工作

  1. 带弹出窗口的控件,例如,组合框、弹出菜单等。
  2. 复选框、单选框。
  3. 皮肤编辑器。

联系作者

  • 邮箱: xinghun87@163.com
  • 博客:https://blog.csdn.net/xinghun61

开源一套DUI控件源码相关推荐

  1. 农历控件源码(C#)

    C#农历控件源码 using System; namespace CNCalendar { public class CNDate { private const ushort START_YEAR ...

  2. Pdf文档在线编辑控件源码及演示

    支持Pdf文档在线编辑,并可以进行另存管理. PdfTestSite为演示文件夹 PdfViewer为控件源码控件 test.pdf为模版文件 注意:服务器端需要安装Adobe Reader以便进行更 ...

  3. Android-UI 超级优良超级多超级强大开源控件源码demo

    第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.Pro ...

  4. Android之PullToRefresh控件源码解析

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/73802453 本文出自:[顾林海的博客] 个人开发的微信小程序,目前功 ...

  5. 日历控件源码开放--适用于ASP.NET 1.1

    摘要:此控件跟据"封装梅花雪疏影横斜"的"Web Calendar ver 3.0 网页日历"提供的JS代码来做的,在此特别感谢. 截图如下: 源码如下: // ...

  6. QT学习之经典控件源码(如此强大)

    进来好好学习了QT,研究了很多别人的源码,在绘图方面原来QT也是如此强大!                                             源码下载: /Files/feiya ...

  7. Android SwipeRefreshLayout下拉刷新控件源码简单分析

    咱们在做Android APP开发的时候经常碰到有下拉刷新和上拉加载跟多的需求,这篇文章咱们先说说下来刷新,咱们就以google的原生的下拉刷新控件SwipeRefreshLayout来看看大概的实现 ...

  8. PhotoView图片缩放控件源码浅析(一)

    本文参考自http://www.tuicool.com/articles/ea2ANjm 简介 PhotoView属性:  可以用于查看图片,并对图片进行拖动缩放,拖动过程中不会出现边缘空白:  双击 ...

  9. c语言即时通讯软件源码,即时通讯软件源码-基于c语言即时通讯软件代码实现

    我不知道哪种语言无关紧要.开源,我不知道该用什么. 即时通讯软件源代码为JAVA语言 对于即时通讯软件源代码最好是用C语言编写的,想学一下,感谢您即时通讯软件有什么. includewinscock2 ...

  10. 超实用的54套ASP网站设计源码

    2019独角兽企业重金招聘Python工程师标准>>> ASP是一种服务器端脚本编写环境,可以用来创建和运行动态网页或Web应用程序.ASP网页可以包含HTML标记.普通文本.脚本命 ...

最新文章

  1. 叶杰平:主流强化学习过分简化假设,与真实场景差距较大
  2. SAP RETAIL 为门店维护多个存储地点
  3. MySQL模拟oracle的connect by
  4. Android18isalone,全新JAVA开发Android程序员需要掌握的英语单词(很全).doc
  5. 洛谷P2708题题解(Java语言描述)
  6. 让sourceSafe每天自动备份及修复(适用于vss6.0和vss2005)
  7. IE无法正常显示中文名图片
  8. WCF BasicHttpBinding 安全解析(3)默认安全设置(IIS宿主)
  9. 《数学之美》—信息的度量和作用
  10. 台安变频器n2按键说明_台安变频器N2
  11. 环境配置系列五Linux.Fedora9.配置
  12. 提供搜题公众号题库接口
  13. 23种设计模式11---享元模式
  14. android 调取数字键盘,Android自定义键盘的实现(数字键盘和字母键盘)
  15. DIY 一个 JSON解析器。
  16. 百度推广系列之广告词编写必杀技
  17. 耳机重装系统后服务器坏了,Win7重装后耳机没声音|重装系统后耳机没声音怎么办?...
  18. 水果店的问题和风险,开水果店会遇到什么问题
  19. DeviceMonitoringStudio设备监控工具的使用
  20. 小米真题:电话号码分身

热门文章

  1. java pdf 页面 拼接_如何使用Java平铺PDF文档中的页面内容?
  2. 风云第三部 第533回 乌云蔽日 力掌乾坤
  3. CIO40知识星球—3年主管升职IT经理(28-30岁)
  4. 如何轻松查询分析多个快递单号物流到站派件延误件
  5. 用n=4的复化Simpson公式求积分方程的近似解[matlab]
  6. 虚幻4随笔(安装与界面说明)
  7. Charles抓包安卓端
  8. 用线性代数解释图论中的一些结论
  9. 艾伦·凯(Alan Kay)的深刻见解
  10. 计算机视觉教程7-3:Openpose配置与实践