我们可以为 CXPButton 类添加各种成员变量。因为自绘控件说穿了就是画图,所以
在成员变量中可以看到各种与画图有关的数据类型,一般来说成员变量会在类的构造函
数中初始化,在类的析构函数中销毁。详细代码请参见本篇附带的源程序。
下面简要叙述一下按钮的实现原理:
1. 在控件初始化时为按钮添加 Owner Draw 的属性。这是因为在 MFC 中,要想激
活控件的自绘功能,要求该控件的属性中必须包含属性值 BS_OWNERDRAW,这一
步我们可以通过类向导为 CXPButton 类添加 PreSubclassWindow()函数,在
该函数中完成属性值的设置。当激活控件的自绘功能之后,每次控件状态改变的时候都
会运行函数 DrawItem(),该函数的作用就是绘制控件在各种状态下的外观。
2. 添加 WM_MOUSELEAVE 消息函数,当鼠标指针离开按钮时,触发该消息函数,
我们在函数中添加代码,通知 DrawItem 函数鼠标指针已经离开了,让按钮重绘。
3. 添加 WM_MOUSEHOVER 消息函数,当鼠标指针位于按钮之上时,触发该消息
函数,我们在函数重添加代码,通知 DrawItem 函数鼠标指针现在正在按钮的上面,
让按钮重绘。
4. 添加 DrawItem 函数。在 DrawItem 中根据按钮当前的状态绘制按钮的外观。
可以说自绘控件的大部分功能都是在这个函数中实现的。DrawItem 函数包含了一个
LPDRAWITEMSTRUCT 的指针,本篇会在稍后予以讲解。
了解了基本的设计思路之后,剩下就看我们怎么去实现了。我本人觉得这里有两个难点,
首先是 WM_MOUSELEAVE 和 WM_MOUSEHOVER 不是标准的 Windows 消
息函数,它们不能通过类向导来添加,所有的添加工作都需要通过手工输入代码来完成。
另一个难点是 DrawItem 中的 LPDRAWITEMSTRUCT 指针,它指向了一个
DRAWITEMSTRUCT 的结构,这个结构中包含了控件的各种细节,为我们提供了实
现自绘功能的必要信息。
难点一:
事实上 WM_MOUSELEAVE 和 WM_MOUSEHOVER 两个 Windows 消息是通
过 WM_MOUSEMOVE 消息触发的,而 WM_MOUSEMOVE 是标准的
Windows 消息,因此我们可以通过类向导来为 CXPButton 类添加
WM_MOUSEMOVE 消息函数。
- 1
- 2
- 3
前往页