专栏导航
上一篇:第4章,[标签 Win32] :获取设备环境句柄的第一个方法
下一篇:无
本节前言
对于本节所讲解的知识,有可能,你会需要时不时地参考本专栏的其它文章。真的遇到了需要参考之前的文章的知识点,请你自行查阅。
我呢,也会提到一部分的参考课节。但是呢,你不应该依赖于我的主动提及。最好呢,你自己能够多去了解和查看本专栏目录。
本节内容,来自对佩措尔德教材内容的大段抄录。
我们开始。
一. 绘制信息结构体的定义
前面曾提到,Windows 将为每个窗口维护一个 "绘制信息结构" ,这便是 PAINTSTRUCT 。这个结构的定义代码如下。
/*** 此结构体定义在 WinUser.h 中 ***/
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT;
当程序调用 BeginPaint 函数时,Windows 将自动填充这个结构体中的字段。程序只能够使用前三个字段,其他的供 Windows 内部使用。
hdc 是设备环境句柄。BeginPaint 函数的返回值就是这个设备环境句柄的值。这里表现了 Windows 典型的冗余性。
关于 fErase 字段,大多数情况下,此字段将被设置为 FALSE,也就是 0 。这意味着,Windows 在先前的 BeginPaint 函数中已经擦除了无效区域的背景。如果想要在窗口过程中自定义背景擦除方式,必须自己处理 WM_ERASEBKGND 消息。在 WinMain 函数初始化时,用于注册窗口类的 WNDCLASS 结构中的 hbrBackground 字段指定了一个画刷,Windows 就使用这个画刷来擦除背景。
很多 Windows 程序指定了一个白色背景画刷。下面的语句可以完成这个任务。
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
但是,当你的程序通过调用 InvalidateRect 函数使客户区中的一个矩形失效时,InvalidateRect 函数的最后一个参数将指定背景是否要被擦除。如果参数是 FALSE,也就是 0,Windows 将不会擦除背景。同时,在调用 BeginPaint 函数之后,PAINTSTRUCT 结构的 fErase 字段的值将是 TRUE (非 0)。
PAINTSTRUCT 结构的 rcPaint 字段将是一个 RECT 类型的结构。在第 3 章中,我们知道,RECT 结构使用 4 个字段,left, top, right 和 bottom 定义了一个矩形。PAINTSTRUCT 结构中的 rcPaint 字段定义了无效矩形的边界。这 4 个字段的值是以像素为单位的,并相对于客户区的左上角。该无效矩形就是用户程序需要进行重新绘制的区域。
PAINTSTRUCT 结构中的 rcPaint 矩形不仅仅是无效矩形,而且还是一个裁剪(Clipping)矩形。这意味着 Windows 将把绘制限制在这个矩形里。更确切地说,如果无效区域不是一个矩形,Windows 将把绘制限制在这个区域内。
在处理 WM_PAINT 消息时,在调用 BeginPaint 之前,调用以下的函数,可以在该更新矩形之外绘制。
InvalidateRect(hwnd, NULL, TRUE);
这个调用将整个客户区无效化,并使其后调用的 BeginPaint 擦除原有的背景。如果将最后的一个参数设置为 FALSE,则随后调用的 BeginPaint 函数将不会擦除背景。也就是说,原来的背景将被保留。
通常来说,对于 Windows 程序,最方便的做法是在收到 WM_PAINT 消息后,简单地重绘整个客户区,而不管 rcPaint 的值如何。例如,如果客户区的显示包括一个圆,但是只有一部分落在无效区域里时,只画这个圆的一部分并不实际。简单的做法是重画整个圆。
在使用从 BeginPaint 函数返回的设备环境句柄时,Windows 无论如何也不会在 rcPaint 定义的矩形之外绘制。
在第 3 章的 HelloWin 程序中,我们在处理 WM_PAINT 消息时,并没有理会无效区域。如果文本显示的地方正好落在无效区域里,DrawText 函数就恢复那块区域。如果没有,那么 Windows 在处理 DrawText 调用时,会发现,它不需要做任何事。但是这个过程要花时间。所以,关心程序运行效率和速度的程序员(我希望每个程序员都会如此)会在处理 WM_PAINT 消息时,使用无效矩形,以避免不必要的 GDI 函数调用。如果绘制时需要从磁盘中读取文件(例如位图文件),这一点尤其重要。
专栏导航
上一篇:第4章,[标签 Win32] :获取设备环境句柄的第一个方法
下一篇:无