通常,应用程序在窗口中绘制以响应
WM_PAINT
消息。 当对窗口的更改更改更改工作区内容时,系统会将此消息发送到窗口过程。 仅当应用程序消息队列中没有其他消息时,系统才会发送消息。
收到
WM_PAINT
消息后,应用程序可以调用
BeginPaint
来检索工作区的显示设备上下文,并在对 GDI 函数的调用中使用它来执行更新工作区所需的任何绘图操作。 完成绘图操作后,应用程序调用
EndPaint
函数以释放显示设备上下文。
在 BeginPaint
返回显示设备上下文之前,系统会为指定的窗口准备设备上下文。 它首先将设备上下文的剪辑区域设置为等于需要更新的窗口部分的交集以及用户可见的部分。 仅重新绘制已更改窗口的那些部分。 尝试在此区域外绘制时会剪裁,并且不会在屏幕上显示。
在
BeginPaint
返回之前,系统还可以将
WM_NCPAINT
和
WM_ERASEBKGND
消息发送到窗口过程。 这些消息指示应用程序绘制非client 区域和窗口背景。
非client 区域
是位于工作区外部的窗口的一部分。 该区域包括标题栏、窗口菜单 (也称为
“系统
”菜单) 和滚动条等功能。 大多数应用程序依赖于默认窗口函数
DefWindowProc
来绘制此区域,因此会将
WM_NCPAINT
消息传递给此函数。
窗口背景
是窗口在其他绘图操作开始之前填充的颜色或图案。 背景覆盖以前在窗口或窗口下的屏幕上的任何图像。 如果窗口属于具有类背景画笔的窗口类,
DefWindowProc
函数会自动绘制窗口背景。
BeginPaint
填充
PAINTSTRUCT
结构,其中包含要更新的窗口部分的维度和指示窗口背景是否已绘制的标志等信息。 应用程序可以使用此信息来优化绘图。 例如,它可以使用
rcPaint
成员指定的更新区域的维度将绘图限制为仅需要更新的窗口部分。 如果应用程序具有非常简单的输出,它可以忽略更新区域并在整个窗口中绘制,依赖于系统放弃 (剪辑) 任何不需要的输出。 由于系统剪辑绘图扩展在剪辑区域之外,因此只有更新区域中的绘图可见。
BeginPaint
将窗口的更新区域设置为
NULL
。 这会清除该区域,防止其生成后续
WM_PAINT
消息。 如果应用程序处理
WM_PAINT
消息,但不调用
BeginPaint
或其他清除更新区域,则只要该区域不为空,应用程序将继续接收
WM_PAINT
消息。 在所有情况下,应用程序必须在从
WM_PAINT
消息返回之前清除更新区域。
应用程序完成绘图后,它应调用
EndPaint
。 对于大多数窗口,
EndPaint
会释放显示设备上下文,使其可用于其他窗口。
EndPaint
还显示插入符号,如果它以前被
BeginPaint
隐藏。
BeginPaint
隐藏插入符号,以防止绘图操作损坏它。
使更新区域失效和验证
检索更新区域
排除更新区域
同步和异步绘图