WM_PAINT是Win32的图形和文本编程中经常使用到的消息。当窗口客户区的一部分或全部变成“无效”时,则必须 “刷新”重绘,此时将向程序发出此消息。
那么客户区怎么会“无效”呢?在最初窗口创建时,整个客户区都是“无效”的,因为窗口上还没有绘制任何东西。所以,在创建窗口时,会发出第一个WM_PAINT消息。
在HelloWin.c程序中,由于在注册窗口时,指定了wndclass.style的风格为CS_VREDRAW和 CS_HREDRAW,这表明只要窗口的高度或宽度发生变化,就将使整个窗口“无效”,从而发出WM_PAINT消息,使得系统重画整个窗口。
当窗口最小化再恢复为以前的大小时,Windows将令窗口“无效”,并发出WM_PAINT消息使系统重画整个窗口。当窗口移至与另一窗口有重叠被遮挡时,Windows也将窗口视为“无效”,发出WM_PAINT消息以便刷新窗口。
在窗口过程函数WndProc中,WM_PAINT消息处理通常总是从BeginPaint函数开始,而从EndPaint函数结束。BeginPaint函数用来返回指定窗口句柄的设备描述表句柄,设备描述表用来将程序与计算机外部输出设备连接起来。 hdc定义的是句柄HDC变量,DrawText等GDI函数都需要通过这样的HDC句柄来绘制图形和文本。EndPaint用来释放设备描述表句柄,并使先前无效区域变为有效,从而使Windows不再发送WM_PAINT消息。PAINTSTRUCT是“绘图信息结构”,BeginPaint和EndPaint函数都需要PAINTSTRUCT结构变量作为自己的参数。需要说明的是,BeginPaint和EndPaint函数必须成对出现,所有GDI函数的调用也应在这两个函数之间进行。
DrawText函数用来在参考矩形内使用指定的格式来绘制文本,它的函数原型如下:
int DrawText( HDC hDC, // 绘制设备的句柄
LPCTSTR lpString, // 要绘制的文本
int nCount, // 文本的字符个数
LPRECT lpRect, // 参考矩形
UINT uFormat // 文本绘制格式
);
其中,当nCount为–1时,表示lpString指定的是以“\0”为结尾的字符串,并自动计算该字符串的字符个数。lpRect是一个指向RECT类型的“矩形”结构指针,该“矩形”结构含有left、top、right和bottom 4个LONG域。为了能在窗口客户区中间绘制文本,该函数的lpRect被填为RECT变量rc的指针,它通过调用GetClientRect函数,获取hwnd窗口的客户区大小。同时,指定uFormat格式为DT_SINGLELINE(单行输出)、DT_CENTER(水平居中)和DT_VCENTER(垂直居中)。