第4章,[标签 Win32] :绘制信息结构

专栏导航

上一篇:第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] :获取设备环境句柄的第一个方法

回到目录

下一篇:无

相关推荐
墨韵流芳1 小时前
CCF-CSP第41次认证第三题——进程通信
c++·人工智能·算法·机器学习·csp·ccf
hz_zhangrl2 小时前
CCF-GESP 等级考试 2026年3月认证C++五级真题解析
c++·青少年编程·程序设计·gesp·c++五级·gesp2026年3月·gesp c++五级
Σίσυφος19002 小时前
C++ 多肽经典面试题
开发语言·c++·面试
桌面运维家2 小时前
Windows权限管理进阶:UAC配置与安全策略实战
windows
crescent_悦3 小时前
C++:The Largest Generation
java·开发语言·c++
我叫洋洋3 小时前
[Proteus 和 stm32f103c8t6]的使用控制OLED篇]
c语言·stm32·单片机·嵌入式硬件·蓝桥杯·proteus
paeamecium4 小时前
【PAT甲级真题】- Student List for Course (25)
数据结构·c++·算法·list·pat考试
Book思议-4 小时前
【数据结构】栈与队列全方位对比 + C 语言完整实现
c语言·数据结构·算法··队列
c++逐梦人6 小时前
C++11——— 包装器
开发语言·c++
桌面运维家7 小时前
BGP路由优化实战:加速收敛,提升网络稳定性
网络·windows·php