如何" BeginPaint"函数知道更新区域 - windows编程?

时间:2015-07-21 02:55:00

标签: c++ windows winapi

我是Windows编程的新手,我有关于绘制窗口的问题,特别是关于BeginPaint函数的问题

当我在MSDN上阅读时,它说

  

通过调用BeginPaint函数启动绘制操作。此函数使用重绘请求的信息填充PAINTSTRUCT结构。当前更新区域在PAINTSTRUCT的rcPaint成员中给出。

我的问题是当我处理WM_PAINT中的wndproc消息并从调用BeginPaint函数开始时,我没有为此函数提供有关特定消息的任何数据我收到了或需要绘制的更新区域那么这个函数如何填充PAINTSTRUCT包括无效的rect" rcPaint成员" ?!

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        // All painting occurs here, between BeginPaint and EndPaint.
        EndPaint(hwnd, &ps);
    }

当我在MSDN上引用BeginPaint函数时,它说

  

除响应WM_PAINT消息外,应用程序不应调用BeginPaint

我的猜测可能是此功能从Windows内部获取此信息 通过请求此信息和发送到窗口的最后一条WM_PAINT消息,我通过它处理"`hwnd'"作为函数的第一个参数。这是对的吗?

提前感谢。

2 个答案:

答案 0 :(得分:5)

我怀疑这是在任何地方记录的,因为它是一个与程序员无关的实现细节,但我很确定更新区域是与HWND一起存储的内部数据结构。您可以判断,因为有几个函数仅基于HWND在更新区域上运行:[In] ValidateRect,[In] ValidateRgn,GetUpdateRgn,BeginPaint等。

答案 1 :(得分:3)

Windows为每个窗口维护一个内部数据结构,该窗口保存其无效区域。 PAINTSTRUCT结构的RECT成员设置为等于此矩形(包含无效区域的最小矩形)。正如user1610015已经指出的那样,这不是程序员通常会遇到的问题。

致电时

hdc = BeginPaint(hwnd, &ps);

使用无效矩形更新PAINTSTRUCTURE结构的RECT结构。

  

我的猜测可能是这个函数从Windows内部获取此信息,请求获取此信息,并将最后一条WM_PAINT消息发送到我通过它的句柄"`hwnd'&# 34;作为函数的第一个参数。这是对的吗?

Windows不会在邮件队列中放置多个WM_PAINT消息。相反,它不断更新窗口更新区域。例如,如果您已在消息队列中有一条WM_PAINT消息,并且在此消息通过调用从队列中删除之前

GetMessage(&msg, NULL, 0, 0)

,验证/更改更新区域(例如通过ValidateRect),然后Windows更新内部更新区域为窗口保持。如果您对ValidateRect的调用验证了整个无效区域,那么WM_PAINT消息将从消息队列中删除,而不会被处理。

此外,当你打电话

hdc = BeginPaint(hwnd, &ps);

您获得的设备上下文(DC)包含一个默认的矩形剪切区域,该区域等于无效矩形(与PAINSTRUCT中的rcPaint设置为相同的矩形)。您无法在剪裁区域外绘制。 例如,您可以使用

偏移剪切区域
// This does not change the update region for the window
// This changes the clipping region associated with the DC hdc
OffsetClipRgn(hdc, xOffset, yOffset);

总而言之,无效区域不一定等于剪切区域(但通常是因为BeginPaint完成了此操作)。窗口的非空无效/更新区域(窗口内部处理)的存在是导致WM_PAINT放入消息队列的原因。