MFC/VC++ UI界面美化技术
1. 工具:
1.1设备环境类:
Windows下的绘图操作说到底就是DC操作。DC(Device Context设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它。这个环境是设备无关的,所以你在对不同的设备输出时只需 要使用不同的设备环境就行了,而作图方式可以完全不变。这也就是Windows的设备无关性。
MFC的CDC类封装了Windows API 中大部分的画图函数。CDC的常见操作函数包括: |
Drawing-Attribute Functions:绘图属性操作,如:设置透明模式 |
Mapping Functions:映射操作 |
Coordinate Functions:坐标操作 |
Clipping Functions:剪切操作 |
Line-Output Functions:画线操作 |
Simple Drawing Functions:简单绘图操作,如:绘制矩形框 |
5 |
Ellipse and Polygon Functions:椭圆/多边形操作 |
Text Functions:文字输出操作 |
Printer Escape Functions:打印操作 |
Scrolling Functions:滚动操作 |
*Bitmap Functions:位图操作 |
*Region Functions:区域操作 |
*Font Functions:字体操作 |
*Color and Color Palette Functions:颜色/调色板操作 |
1.2图形对象类
设备环境不足以包含绘图功能所需的所有绘图特征,除了设备环境外, Windows还有其他一些图形对象用来储存绘图特征。这些附加的功能包括从画线的宽度和颜色到画文本时所用的字体。图形对象类封装了所有六个图形对象。
下面的表格列出了MFC的图形对象类:
MFC类 图形对象句柄 图形对象目的
CBitmap HBITMAP 内存中的位图 |
CBrush HBRUSH 画刷特性—填充某个图形时所使用的颜色和模式 |
CFont HFONT 字体特性—写文本时所使用的字体 |
CPalette HPALETTE 调色板颜色 |
CPen HPEN 画笔特性—画轮廓时所使用的线的粗细 |
CRgn HRGN 区域特性—包括定义它的点 |
2. 界面美化的实现
2.1 界面美化的方法:
2.1.1 使用MFC的既有函数,设定界面属性
2.1.2 利用Windows的消息机制,截获有用的Windows的消息。通过MFC的消息映射(Message Mapping)和反射(Message Reflecting)机制,在Windows准备或者正在绘制该元素时,偷偷修改它的状态和行为,譬如:让按钮的边框为红色。
2.2.3利用MFC类的虚函数机制,重载有用的虚函数。在MFC框架调用该函数的时候,重新定义它的状态和行为
在应用程序中,一般通过以下两种方案实现以上方法:
- 在父窗口里,截获自身的或者由子元素(包括控件和菜单等元素)传递的关于界面绘制的消息;
- 子类化子元素,或者为子元素准备一个新的类(一般来说该类必须继承于MFC封装的某个标准类,如:CButton)。在该子元素里,截获自身 的或者从父窗口反射过来的关于界面绘制的消息。譬如:用户可以创建一个CXPButton类来实现具有XP风格的按钮,CXPButton继承于 CButton。
对于应用程序,使用CXPButton类的途径相对于对话框窗口和普通窗口分成两种:
① 对话框窗口中,直接将原先绑定按钮的CButton类替换成CXPButton类,或者在绑定变量时直接指定Control类型为CXPButton。
②在普通窗口中,直接创建一个CXPButton类对象,然后在OnCreate()中调用CXPButton的Create方法
2.2 使用MFC的基本既有函数
(1) 指定对话框的文本色和背景色
CListCtrl::SetBkColor
CRebarCtrl::SetBkColor
CStatusBarCtrl::SetBkColor
CTreeCtrl::SetBkColor
CListCtrl::SetTextColor
CRebarCtrl::SetTextColor
CStatusBarCtrl::SetTextColor
CTreeCtrl::SetTextColor
(2) 设定控件背景图片
CListCtrl::SetBkImage
2.3 使用Windows消息机制
Windows是通过消息机制进行通讯的,那么我们就可以通过截获一些有用的消息来美化我们的界面,以下是一些常用的Windows消息:(标注*的消息是子元素发送给父窗口的通知消息,其它的为窗口或者子元素自身的消息。
)
WM_PAINT
WM_ERASEBKGND
WM_CTLCOLOR*
WM_DRAWITEM*
WM_MEASUREITEM*
NM_CUSTOMDRAW*
2.4 WM_PAINT
WM_PAINT 就是窗口要重绘了,会发个WM_PAINT消息给窗口,响应窗口的WM_PAINT
2.5 WM_ERASEBKGND
Windows在向窗口发送WM_PAINT消息之前,总会发送一个WM_ERASEBKGND消息通知该窗口擦除背景,默认情况下,Windows将以窗口的背景色清除该窗口。
可以响应窗口(包括子元素)的WM_ERASEBKGND,以更改它们的背景。WM_ERASEBKGND的映射函数原型如下:
afx_msg BOOL OnEraseBkgnd( CDC* pDC );
返回值:
指定背景是否已清除,如果为FALSE,系统将自动清除
参数:
pDC指定了绘制操作所使用的设备环境。
2.6 WM_CTLCOLOR
在控件显示之前,每一个控件都会向父对话框发送一个WM_CTLCOLOR消息要求获取绘制所需要的颜色。WM_CTLCOLOR消息缺省处理函数 CWnd::OnCtlColor返回一个HBRUSH类型的句柄,这样,就可以设置前景和背景文本颜色,并为控件或者对话框的非文本区域选定一个刷子。
WM_CTLCOLOR的映射函数原型如下:
afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );
返回值:
用以指定背景的刷子
参数:
pDC指定了绘制操作所使用的设备环境。
pWnd 控件指针
nCtlColor 指定控件类型,其取值如下所示:
类型值 含义
CTLCOLOR_BTN 按钮控件
CTLCOLOR_DLG 对话框
CTLCOLOR_EDIT 编辑控件
CTLCOLOR_LISTBOX 列表框
CTLCOLOR_MSGBOX 消息框
CTLCOLOR_SCROLLBAR 滚动条
CTLCOLOR_STATIC 静态控件
2.7 WM_DRAWITEM、
OnCtlColor只能修改元素的颜色,但不能修改元素的界面框架,WM_DRAWITEM则可以。
当一个具有Owner draw风格的元素(包括按钮、组合框、列表框和菜单等)需要显示外观时,该元素会发送一条WM_DRAWITEM消息至它的隶属窗口(Owner)。一般自绘或重写按钮控件都必须实现该函数。
WM_DRAWITEM的映射函数原型如下:
afx_msg void OnDrawItem( int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct );
2.8 WM_MEASUREITEM
有时候仅仅WM_DRAWITEM还是不够的,对于一些特殊的控件,如ListBox,系统在发送WM_DRAWITEM消息前,还发送WM_MEASUREITEM消息,需要你设置ListBox中每个项目的高度或宽度等。
WM_DRAWITEM的映射函数原型如下:
afx_msg void OnMeasureItem( int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct );
当然,使用这个的前提必须把 控件设置为 Owner draw 属性。
3. 使用MFC的虚函数机制
对界面按钮重绘主要就是在DrawItem中根据按钮当前的状态绘制按钮的外观。可以说自绘控件的大部分功能都是在这个函数中实现的。DrawItem函数包含了一个LPDRAWITEMSTRUCT的指针。