MFC/VC++ UI界面美化技术

时间:2021-02-07 16:58:39


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框架调用该函数的时候,重新定义它的状态和行为

在应用程序中,一般通过以下两种方案实现以上方法:

  1. 在父窗口里,截获自身的或者由子元素(包括控件和菜单等元素)传递的关于界面绘制的消息;
  2. 子类化子元素,或者为子元素准备一个新的类(一般来说该类必须继承于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的指针。