基于DirectUI 的SCW- App 主体部分的思路总结
基于 C++ 的 SC DirectUI 界面库的想法与实现到今天也有近半个月了。一些新的想法与思路在学习和实践中得到了提高。推翻重来,重复再干,虽然是件苦事,但,不得不为之。这样才能有所提高。
上一篇: 基于DirectUI的SC设计规划的个人构想与目标
设计 SCW时,曾总结了一下程序的组成部分:
- 全局: 管理程序中唯一性的数据成员,对象成员等。
- 桌面: 与系统桌面相关的一些参数或功能。比如桌面的屏幕大小,鼠标形状等。
- 窗口: 负责注册窗、创建、显示、销毁窗口以及其他与窗口相关的功能。
- 事件: Windows系统下的消息处理。包括启动消息循环、过滤、派发等。
- 绘图: 实现对窗口或打印机的绘图输出。通过GDI+或Direct2D等支持库来完成。负责界面基本元素的功能实现。
- 组件: 组成窗口界面与事件处理的一系列控件。如 Label, Button, Edit等。
- 资源: 统一管理与分配程序中的图片、文本、字体等资源。包括实现界面主题、多语种等因素。
- 功能: 程序最终要要完成的功能任务。
在以上总结的基础上,完成SCW 的控制类 CWinApp时。曾计划了两套方案。
- 在考虑跨平台下,参考了FireMonkey的思路,将各个功能部分以接口的形式,分别创建了不同的接口类。也已经基本实现了窗口 IWindowService、消息 IApplicationService、绘图 CCanvas三个主体类部分的代码。主控类CWinApp分别继承了WindowService, IApplicationService 来实现主体功能。
- 后来因想加快速度,先不考虑不跨平台了,想集中精力实现Windows下的DirectUI界面库时。重新设计了CWinApp。想简化思路,就将原来的代码全部集合到一个CWinApp上。只将绘图部分离出来了。也完成了这三个部分的基础代码。
但是,今天在重新审视框架时,发现这种两种设计都存在缺点:
- 功能太集中。在一个CWinApp类里,同时实现了窗口,消息、资源管理功能。虽然这些功能都是 一个App 应该完成的任务,但是集中写到一个App。并不是一个好的主意。虽然上面第一种方案有将功能分解成不同的接口类,但是以继承派生的方式又集合到了一个CWinApp上。FireMonkey的思路虽然有好的地方,但是这种集合性功能,仍不方便。
- 功能太集中还会造成代码也集中。在测试与更新代码时。需要一堆过程函数中逐个去寻找,并定位到功能代码块。对以后的维护与完善也不是好事。
- 封装不灵活,特别是第二种方案,虽然简化了思路,只想由一个App类来解决所有问题。但同时也造成 App功能模块的臃肿。扩展性也不方便灵活。虽然继承、重写可以实现扩展,但容易出错,且需要虚拟很多过程来实现继承的目的。第一种方案较第二种强点,可以通过改写接口类来实现跨平台(FireMonkey是这样实现的),由于是继承接口类派生来来,扩展性仍然是问题。
总结以上的问题,加上自己在堆代码,学习C++时的不断深入,对框架有了新的理解和更方便的解决方案。所以整理出来,从新设计 SCW – App 部分的框架。
主体想法是,仍采用功能分离的方式,生成不同的类。但不使用继承的方式,而是以静态指针的方式,动态生成不同功能类的实体。再统一由CApp类来管理这些功能类。构想如下:
- CGlobal 注册并管理 CApp实体, 程序内其他对象可以访问 CGlobar及CApp
- CApp动态创建各个功能类。如CScreen, CMsgController等。虚拟的创建过程可继承重写。方便扩展。
- CApp的各个功能类允许程序内其他对象访问,以完成对应的功能。
SCW-主体结构规划如下:
- 全局类 CGlobal
注册 CApp类。其他对象可以通过这个全局类来访问当前 CApp的实现,并实现相关功能。
管理全局性唯一对象。如桌面,鼠标,当前激活窗口,集点控件等。
全局参数的设置。如字体,界面主题、语种等。
全局类 CGlobal 是一个静态对象实体,程序运行时即被产生。 - 主控类 CWinApp
由程序动态产生,可扩展。创建时,将实体指针直接注册到 CGlobal中。
主要完成与程序相关的基本功能。
负责管理并生成其他功能类。可继承重写生成过程,能实现添加新的功能控制类或注册新的功能控制派生类。大大提高了可扩展性。
负责注册绘图引擎。可继承重写,能注册不同的绘图引擎。 - 桌面类 CScreen
可扩展,由CApp动态产生。提供与系统桌面相关的参数设置与功能函数。 - 消息处理类 CMsgController
可扩展,由CApp动态产生。提供消息循环、处理、派生等功能。是窗口及窗口内控件实现界面刷新与操作响应的核心中间件。
- 窗口控制类 CWndManager
可扩展,由CApp动态产生。提供窗口注册、创建、销毁等功能。
- 绘图引擎类 CCanvas
可扩展,由CApp负责注册。由具体的窗口生成绘图实体。提供窗口及控件界面绘制的基本功能。是DirectUI界面实现的核心中间件。
- 组件类 CObject
派生并产生各种界面组件与功能组件。是实现DirectUI理念的核心中间件。
- 其他
就是其他,仅仅是其他。想到的,需要的功能。
从最初计划设计并想完成 SCW 的 DirectUI界面库到现在。我在程序框架与基础代码上花了不少时间,反复几次,不断修改。目的就是想边学习,边实践,边总结。在保证基础框架更科学,更理想的情况下,努力提高自己的想法,在实践中得出经验后,再不断挖掘自己的能力。虽然框架多次改写,重构,貌似复杂劳动了很多次。但每次都有提高。一个人,虽然没有人多集思广益的好处。但也可以这么任性。
开始时多花点时间,甚至推翻重来,反复几次。这样才能保证基础的扎实,这样才能提高自己。不满足与高要求,是做好任何一件事的基础。这次的总结,估计也不会是最后一次的总结。都说写代码苦,现在终于体会到了。苦不是在于努力地敲键盘,而是,永远有更好,永远不能满足。这种也是:苦,并快乐着。有兴趣才是对的。
贴出来,是希望有心人能提供更多的帮助。
有兴趣的朋友也可以加Q或群进行交流:
QQ群:177312461 个人QQ:48018276