720 likes | 1.1k Views
WINX A C++ Template GUI Library. 许式伟 2006-3-3. 纲要. C++ 程序员的困惑 谈谈 WINX 的设计目标 WINX 概览 WINX 作为界面库的特性 界面风格问题 WINX 的高级特性 WINX 对自动化的支持 自动化支持与 ATL 相比足够简化、易用。 WINX 对 IPC 的支持 进程间的通讯 WINX 对对大型程序的支持 WINX 的大型程序设计的理念. WINX 的设计目标. C++ 程序员的困惑 WINX 的目标. C++ 程序员的困惑. 内存管理 垃圾回收器?
E N D
WINXA C++ Template GUI Library 许式伟 2006-3-3
纲要 • C++程序员的困惑 • 谈谈WINX的设计目标 • WINX概览 • WINX作为界面库的特性 • 界面风格问题 • WINX的高级特性 • WINX对自动化的支持 • 自动化支持与ATL相比足够简化、易用。 • WINX对IPC的支持 • 进程间的通讯 • WINX对对大型程序的支持 • WINX的大型程序设计的理念
WINX的设计目标 • C++程序员的困惑 • WINX的目标
C++程序员的困惑 • 内存管理 • 垃圾回收器? • 解决方案: WINX!( AutoFreeAlloc等) • 界面编程 • 可视化? • 属性编程?事件? • 解决方案:WINX! • 自动化支持(Automation) • Dispatch调用?连接点? • 解决方案:#import + WINX! • 进程间通讯(IPC) • 解决方案:WINX! • 大型程序支持 • 如何解耦?Document/View? • WINX的界面设计理念不是MFC简单的Document/View模型。
WINX的目标 • 轻巧、易用、“傻瓜式” • 属性编程(类Delphi) • 可视化 • 事实:WTL的很多关键特性在模态对话框中不可用。例如PreTranslateMessage (包括快捷键的支持)、UpdateUI等等。 • 与WTL对模态对话框的“轻视”相反,WINX极大化的强化模态对话框的能力。从而使得多数的界面设计可以以可视化方式完成。
WINX中的基本概念 • 基础类(BasicTypes) • 句柄类(HandleClass) • 窗口类(WindowClass) • 消息(WindowMessage) • 属性(Property) • 行为(WindowBehavior)
WINX中的基本概念 • 基础支撑 • 基础类(BasicTypes),多数来自WTL • 辅助:调试诊断等 • 句柄类(HandleClass) • Win32 SDK中的句柄的简单包装 • WINX的所有句柄类直接取自ATL/WTL • 窗口类(WindowClass) • 消息(Message)的接收者 • 窗口类不一定要保存有窗口句柄(!!!) • 消息(WindowMessage) • 消息分派(DispatchMessage) • 属性(Property) • 属性编程(类Delphi),易往可视化发展
基础支撑 • 基础支撑的实现原则 • 基础类(BasicTypes) • 辅助
基础支撑的实现原则 • 不假设自己是用户独立使用的库。 • 所以尽量检测用户是否使用了某种流行的库,选择该库已有的。 • 举例:WINX_ASSERT #if defined(ASSERT) #define WINX_ASSERT(e) ASSERT(e) #elif defined(_ASSERTE) #define WINX_ASSERT(e) _ASSERTE(e) #else # ifdef _DEBUG # define WINX_ASSERT(e) assert(e) # else # define WINX_ASSERT(e) 0 # endif #endif
基础类(BasicTypes)列表 • 来自WTL • CPoint • CRect • CSize • CString • CFindFile • CRecentDocumentList • 辅助 • WindowRect • ClientRect
辅助 • 通用 • _offsetof、parent_class_ptr、countof • MsgBox • WINX_DEFINE_IID、WINX_UUID • 调试/诊断 • WINX_ASSERT • WINX_ASSERT_OK • WINX_ASSERT_ONCE • WINX_ASSERT_DERIVE • WINX_REPORT • WINX_VERIFY • WINX_VERIFY_OK • WINX_TRACE
句柄类(HandleClass)列表 • 窗口句柄类 • Static、RichEdit等 • 资源句柄类 • 图片、光标、图标等 • GDI句柄类 • DC、Pen、Brush等 • 其他句柄类 • ImageList等
窗口句柄类 • WindowHandle - ATL::CWindow • AxCtrlHandle - ATL::CAxWindow • ActiveX控件句柄类 • StaticHandle - WTL::CStatic • ButtonHandle - WTL::CButton • EditHandle - WTL::CEdit • ComboBoxHandle - WTL::CComboBox • ScrollBarHandle - WTL::CScrollBar • FlatScrollBarHandle - WTL::CFlatScrollBar • ListBoxHandle - WTL::CListBox • DragListBoxHandle - WTL::CDragListBox • ListCtrlHandle - WTL::CListViewCtrl • HeaderCtrlHandle - WTL::CHeaderCtrl • TreeCtrlHandle - WTL::CTreeViewCtrl
窗口句柄类(2) • ToolBarCtrlHandle - WTL::CToolBarCtrl • TabCtrlHandle - WTL::CTabCtrl • ToolTipCtrlHandle - WTL::CToolTipCtrl • StatusBarCtrlHandle - WTL::CStatusBarCtrl • SliderCtrlHandle/TrackBarCtrlHandle - WTL::CTrackBarCtrl • SpinButtonCtrlHandle/UpDownCtrlHandle - WTL::CUpDownCtrl • ProgressCtrlHandle - WTL::CProgressBarCtrl • HotKeyCtrlHandle - WTL::CHotKeyCtrl • AnimateCtrlHandle - WTL::CAnimateCtrl • ReBarCtrlHandle - WTL::CReBarCtrl • ComboBoxExHandle - WTL::CComboBoxEx • DateTimeCtrlHandle - WTL::CDateTimePickerCtrl • MonthCalCtrlHandle - WTL::CMonthCalendarCtrl • IPAddressCtrlHandle - WTL::CIPAddressCtrl • PagerCtrlHandle - WTL::CPagerCtrl • RichEditHandle - WTL::CRichEditCtrl
资源句柄类 • BitmapHandle - WTL::CBitmapHandle • Bitmap - WTL::CBitmap • IconHandle - WTL::CIconHandle • Icon - WTL::CIcon • CursorHandle - WTL::CCursorHandle • Cursor - WTL::CCursor • MenuHandle - WTL::CMenuHandle • Menu - WTL::CMenu • AcceleratorHandle - WTL::CAcceleratorHandle • Accelerator - WTL::CAccelerator
GDI句柄类 • RgnHandle - WTL::CRgnHandle • Rgn - WTL::CRgn • PenHandle - WTL::CPenHandle • Pen - WTL::CPen • BrushHandle - WTL::CBrushHandle • Brush - WTL::CBrush • FontHandle - WTL::CFontHandle • Font - WTL::CFont • PaletteHandle - WTL::CPaletteHandle • Palette - WTL::CPalette • EnhMetaFileHandle - WTL::CEnhMetaFileHandle • EnhMetaFile - WTL::CEnhMetaFile
GDI句柄类 – DC • DCHandle - WTL::CDCHandle • ClientDC - WTL::CClientDC • WindowDC - WTL::CWindowDC • PaintDC - WTL::CPaintDC • MemoryDC - WTL::CMemoryDC • EnhMetaFileDC - WTL::CEnhMetaFileDC
其他句柄类 • ImageListHandle - WTL::CImageList
窗口类(WindowClass) • 窗口分类 • 窗口类的注册 • 通用控件的窗口类 • 属于SubclassWindow • 子类化(或:超类化) • 使用高版本特有控件 • SafeCtrl
窗口分类 • Window • 普通窗口,例:Hello, Winx!!! • SubclassWindow • 子类(Subclass),例:禁止Edit的右键菜单 • 超类(Superclass),例:禁止Edit的右键菜单 • LightSubclassWindow • 对一个窗口子类化,轻量级,这要求窗口类没有数据。 • LightSuperclassWindow • 对一个窗口超类化,轻量级,这要求窗口类没有数据。 • ModalessDialog • 非模态对话框,例:将对话框嵌入到另一个对话框 • 对话框超类,例:将对话框嵌入到另一个对话框 • ModalDialog/AxModalDialog • 模态对话框,例:Hello, Winx!!! • 允许插入ActiveX控件的对话框,例:嵌入IE
窗口类的注册 • MFC、WTL弱化了窗口类的注册,与此相反,WINX强调窗口类概念,并要求用户主动注册窗口类。 • 表面上看,WINX的用法比MFC、WTL繁琐了(多了主动RegisterClass过程),但是深究下去,你将发现这恰恰是WINX推崇可视化界面开发的关键点。 • 窗口类注册相关 • WINX_CLASS • WindowClass::RegisterClass • 只有普通窗口、窗口超类(Superclass)需要注册。子类化窗口、普通对话框不需要注册。 • RegisterClass相关的例子: • 普通窗口,例:Hello, Winx!!! • 超类(Superclass),例:禁止Edit的右键菜单 • 对话框超类,例:将对话框嵌入到另一个对话框
通用控件的窗口类(列表) 考虑到MFC的接受程度远远高于WTL,故此命名以兼容MFC为主。 • Static/Button/Edit/ComboBox • ScrollBar/FlatScrollBar • ListBox/DragListBox • ListCtrl/HeaderCtrl/TreeCtrl • ToolBarCtrl/ReBarCtrl • SliderCtrl(即:TrackBarCtrl) • SpinButtonCtrl(即:UpDownCtrl) • TabCtrl/ToolTipCtrl/StatusBarCtrl/ProgressCtrl • HotKeyCtrl/AnimateCtrl/IPAddressCtrl • DateTimeCtrl/MonthCalCtrl • ComboBoxEx/RichEdit • LinkCtrl
使用高版本特有控件 • SafeCtrl • 这是一个特殊的窗口类。在以下用况使用: • 高版本Windows提供了一个控件(例如LinkCtrl)。我们希望在该版本的Windows版本使用它,而在低版本的Windows下,我们提供一个替换控件(AltCtrl)。 • 我们使用了一个第三方控件。我们希望在用户安装了该控件时使用它,否则使用替换控件(AltCtrl)。 • 概念 • OrgCtrl/OrgClassName • 高版本Windows提供(或第三方提供)的控件 • AltCtrl/AltClassName • 替换控件。你需要实现的。 • SafeCtrl/SafeClassName • 安全控件。WINX提供的。例如SafeLinkCtrl。
消息(WindowMessage) • 消息分派总流程 • DispatchMessage • 消息分类 • 位置消息、焦点消息等 • 局部分派 • 命令分派(Command) • 通知分派(Notify) • 键盘与快捷键 • 反射(Reflect)
消息分派(DispatchMessage) • 消息分派机制是WINX的特色之一。 • 区别于WTL或者MFC,你不需要主动写一个消息分派的映射表。 • WINX易用性的第一体现。 • 高性能 • WINX为了实现消息分派使用了一个庞大的虚表?NO! • 对比产生的汇编代码表明,WINX的消息分派产生的代码比WTL和MFC更为短小精悍。
WINX和WTL消息分派的比较 • 各有特色 • WTL:强灵活性,容易进行第三方的功能扩展。缺点是看起来比较丑陋。 • WINX:强调易用性,并且实现了用户不需要某个特性时无额外开销。故此,系统可以不断的进行新特性的添加(但是缺点是不能以第三方的方式添加——注:当然你可以按WTL的方式进行功能扩展,在WINX中这是允许的,但与WINX的设计理念有背)。
消息分类 • 位置事件(MouseEvent) • 焦点事件(Keyboard、Accel、Command) • 目标的不确定性,是焦点事件(Focus Message)最显著特征。 • 绘制事件(Paint/NcPaint/EraseBkgnd等) • 定时事件(Timer) • 通知事件 • 子通知父 • 系统通知 • 广播
命令分派(Command) • 命令事件 • WINX_CMDS_BEGIN [_EX] • WINX_CMD • WINX_CMD_EX • WINX_CMDS_END [_EX] • ForwardCommand • WINX_CMDS_BEGIN_EX/END_EX配对,区别与WINX_CMDS_BEGIN/END的是,如果消息自身没有处理,会发给活动的子视图处理。
命令状态(UpdateUI) • WTL的命令状态维护机制不错,但是ModalDialog不完全支持该机制。主要的问题在于没有OnIdle消息。 • WINX的UpdateUI基于WTL的命令状态维护机制实现,并作出改进。
区别:命令状态机制与界面更新 • 相同点: • 均属于界面更新。所以理论上也可以使用界面更新机制来进行命令状态的更新。 • 区别: • 界面更新机制更关注的是界面与其他组件的交互(订阅事件、响应事件)。 • 命令状态更新是比较细粒度的界面更新过程。用事件订阅有时显得不值得。因此,通常命令状态更新是一个OnIdle过程。
键盘与快捷键(Keyboard&Accel) • 和命令一样,属于焦点事件,有事件的目标窗口不确定性。 • 考虑用况:整个应用程序支持Undo/Redo,但是程序某个时刻处于一个Edit控件中,此时希望Undo/Redo是Edit控件的文本,而不是应用程序一级的Undo/Redo。 • 解决方案: • 使用ForwardCommand • 使用TestTranslateAccel(见后文)
通知消息分派(Notify) • WINX_NOTIFY_BEGIN • WINX_NOTIFY • WINX_NOTIFY_END
反射(Reflect) • WINX_REFLECT • 反射,即将子窗口发给父窗口的消息返回给子窗口自己处理。反射机制通常用于解耦。 • WINX_REFLECT_CMD • WINX_REFLECT_CMDS_BEGIN • WINX_REFLECT_CMD • WINX_REFLECT_CMDS_END • WINX_REFLECT_NOTIFY • WINX_REFLECT_NOTIFY_BEGIN • WINX_REFLECT_NOTIFY • WINX_REFLECT_NOTIFY_END
鼠标滚轮消息 • WM_MOUSEWHEEL • Note: SetFocus();
属性(Property) • 属性 • 属性命名规则 • 支持的属性列表
属性 • 基于属性的编程,容易向可视化发展。 • Delphi中优良的用户体验 • 区别于Delphi:如果某个特性没有使用,不会带来额外的代价。
属性的命名规则 • 规则 • WINX[_适用范围]_属性[_属性子类] • WINX_BKGND_PATTERN • 其中,BKGND为属性,PATTERN为属性子类。 • WINX_APP_ICON • 其中,APP为适用范围,ICON为属性。 • WINX_SYSICON • 有时,为了减少宏名长度,在属性子类可以表意的情况下,可以省略属性。如:WINX_SYSICON,完整名应该称为WINX_ICON_SYSICON。 • 适用范围 • WINX_XXX • 该属性所有窗口均适用 • WINX_DLG_XXX • 该属性只在对话框类中使用。 • WINX_APP_XXX • 该属性属于Application属性,应该在WinMain函数中使用。这类属性比较特殊,属于全局设置,作用于所有窗口。 • ......
WINX支持的属性列表 • 快捷键(Accel) • 窗口图标(Icon) • 窗口背景(Bkgnd) • 窗口子控件统一背景(CtlBkgnd) • 窗口Resize最小大小(MinInfo) • 窗口布局(Layout) • 窗口锚点(Anchor - todo) • 应用程序图标(AppIcon) • 应用程序菜单风格(AppMenu - todo) • 应用程序观感(AppLookNFeel - todo)
WINX_ACCEL • WINX_ACCEL • 指定一个窗口的快捷键表 • WINX_DLG_ACCEL • 对话框及其子控件支持快捷键,默认不支持。 • TestTranslateAccel • 快捷键派发机制的修正。因为父窗口可能截获子窗口的快捷键。故此提供一个修正机会。
WINX_ICON • 设置窗口的图标 • WINX_ICON • WINX_ICONSM • WINX_SYSICON • WINX_SYSICONSM
WINX_BKGND • 设置窗口背景 • WINX_BKGND_COLOR 例:WINX_BKGND_COLOR(COLOR_WINDOW); • WINX_BKGND_BRUSH 例: WINX_BKGND_BRUSH(GRAY_BRUSH); • WINX_BKGND_PATTERN 例:WINX_BKGND_PATTERN(IDB_BKGND); 功能:以资源文件中的一幅位图作为窗口背景 • WINX_BKGND_NULL 功能:透明背景。
WINX_CTLBKGND • 类似于WINX_BKGND,但是是统一设置某类型的子控件背景。 • WINX_CTLBKGND_COLOR • WINX_CTLBKGND_BRUSH • WINX_CTLBKGND_PATTERN • WINX_CTLBKGND_NULL • WINX_CTLBKGND_NULL_ALL
WINX_MININFO • 设置窗口的最小SIZE • WINX_MININFO • WINX_MININFO_PT • WINX_MININFO_DEFAULT
设置窗口布局(1) • WINX_ANCHOR • 子控件使用,指定自己的Anchor方法。 • 暂屏蔽。
设置窗口布局(2) • 提供以下方案: • WINX_DLGRESIZE_BEGIN • WINX_DLGRESIZE • WINX_DLGRESIZE_END • 这是利用WTL提供的DLGRESIZE_MAP实现,使用上略有简化。 • 例子: • Layout
WINX_APP_ICON • 设置应用程序图标。 • 这将使得所有有标题的弹出窗口自动设置了该图标(除非该窗口使用WINX_ICON自己设置了图标)。 • 包括MessageBox。
WINX_APP_MENU • 设置应用程序菜单的风格。 • 自动、强制经典风格、强制XP风格。 • 暂屏蔽。
WINX_APP_LOOKNFEEL • 设置应用程序的总体风格。包括AppIcon、AppMenu的设定。 • 从用户角度来讲,它只是一个AppIcon、AppMenu的组合属性。但应当注意,它比单独指定AppIcon、AppMenu有一点点的性能优势。 • 暂屏蔽。
窗口行为(WindowBehavior) • 窗口行为 • 行为的禁止/许可 • 行为的切换
窗口行为 • 可以施加于任何窗口上的行为特征 • WINX_BEHAVIOR • 目前支持的行为列表 • DefaultBehavior(无行为) • Moveless(不可移动) • WithinScreen(不可出屏幕) • LimitScreenTop/Left/Right • AutoHiddenTop/Left/Right(在上/左/右方自动隐藏) • AutoHiddenAnySide(自动隐藏) • FullScreenDockable(全屏停靠在窗口的左/右方)