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

回到目录

下一篇:无

相关推荐
WBluuue2 小时前
AtCoder Beginner Contest 441(ABCDEF)
c++·算法
南 阳2 小时前
Python从入门到精通day10
linux·windows·python
晨非辰2 小时前
C++波澜壮阔40年|类和对象篇:拷贝构造与赋值重载的演进与实现
运维·开发语言·c++·人工智能·后端·python·深度学习
未来龙皇小蓝2 小时前
策略模式:Spring Bean策略与枚举 Lambda策略
java·windows·spring boot·spring·策略模式
hetao17338372 小时前
2026-01-16~19 hetao1733837 的刷题笔记
c++·笔记·算法
玖釉-2 小时前
[Vulkan 学习之路] 29 - 加载模型 (Loading Models)
c++·windows·图形渲染
凯子坚持 c2 小时前
在 Visual Studio 2019 中配置 Qt 插件开发环境:编译原理 + 底层逻辑解析
ide·qt·visual studio
逐浪CMS发哥2 小时前
windows删除字体缓存(即删除用户目录下的字体文件)
windows·缓存
HelloWorld1024!2 小时前
C++中链表的虚拟头结点:应用场景与使用时机
网络·c++·链表