WM_PAINT消息

通常,应用程序在窗口中绘制响应 WM_PAINT 消息。 当对窗口的更改更改更改了工作区的内容时,系统会将此消息发送到窗口过程。 仅当应用程序消息队列中没有其他消息时,系统才发送消息。

收到 WM_PAINT 消息后,应用程序可以调用 BeginPaint 来检索工作区的显示设备上下文,并在调用 GDI 函数时使用它来执行更新工作区所需的任何绘图操作。 完成绘图操作后,应用程序调用 EndPaint 函数以释放显示设备上下文。

在 BeginPaint 返回显示设备上下文之前,系统会为指定窗口准备设备上下文。 它首先将设备上下文的剪辑区域设置为等于需要更新的窗口部分和用户可见部分的交集。 仅重绘已更改的窗口部分。 尝试在此区域外绘制时,会进行剪裁,并且不会显示在屏幕上。

系统还可以在 BeginPaint 返回之前将WM_NCPAINTWM_ERASEBKGND消息发送到窗口过程。 这些消息指示应用程序绘制非工作区和窗口背景。 非工作区是工作区外部的窗口的一部分。 该区域包括标题栏、窗口菜单 (也称为 系统 菜单) 和滚动条等功能。 大多数应用程序依赖于默认窗口函数 DefWindowProc 来绘制此区域,因此将 WM_NCPAINT 消息传递给此函数。 窗口背景是窗口在其他绘制操作开始之前填充的颜色或图案。 背景覆盖以前在窗口或窗口下的屏幕上的任何图像。 如果窗口属于具有类背景画笔的窗口类, DefWindowProc 函数会自动绘制窗口背景。

BeginPaint 使用诸如要更新的窗口部分的尺寸和指示是否已绘制窗口背景的标志等信息填充 PAINTSTRUCT 结构。 应用程序可以使用此信息来优化绘图。 例如,它可以使用 由 rcPaint 成员指定的更新区域的尺寸,将绘图限制为仅需要更新的窗口部分。 如果应用程序具有非常简单的输出,它可以忽略更新区域并在整个窗口中绘制,依赖于系统放弃 (剪辑) 任何不需要的输出。 由于系统剪裁在剪裁区域外延伸的绘图,因此只有更新区域中的绘图可见。

BeginPaint 将窗口的更新区域设置为 NULL。 这会清除该区域,阻止其生成后续 WM_PAINT 消息。 如果应用程序处理 WM_PAINT 消息,但不调用 BeginPaint 或以其他方式清除更新区域,则只要该区域不为空,应用程序将继续接收 WM_PAINT 消息。 在所有情况下,应用程序必须在从 WM_PAINT 消息返回之前清除更新区域。

应用程序完成绘制后,应调用 EndPaint。 对于大多数窗口, EndPaint 会释放显示设备上下文,使其可供其他窗口使用。 EndPaint 还会显示插入点(如果它以前被 BeginPaint 隐藏)。 BeginPaint 隐藏插入点以防止绘图操作损坏它。