首页 > 解决方案 > 在 Windows 上绘制客户区时“清除更新区域”是什么意思?

问题描述

在这里画窗提到:

绘制完客户区后,清除更新区域,这会告诉操作系统它不需要发送另一个 WM_PAINT 消息,直到发生变化。

可以编写以下代码:

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            RECT rect;
            GetClientRect(hWnd, &rect);
            HBRUSH brush = CreateSolidBrush(RGB(127, 127, 127));

            FillRect(hdc, &rect, brush);

            const wchar_t * lstr = L"here is information";
            TextOut(hdc,
                5, 5,
                lstr, _tcslen(lstr));


            DrawText(hdc, TEXT("Singleline in center~"), -1, &rect,
                DT_SINGLELINE | DT_CENTER | DT_VCENTER);

            MoveToEx(hdc, 50, 100, NULL);
            LineTo(hdc, 44, 10);
            LineTo(hdc, 78, 40);

            Rectangle(hdc, 16, 36, 72, 70);
            Rectangle(hdc, 34, 50, 54, 70);

            DeleteObject(brush);

            EndPaint(hWnd, &ps);
        }

这里的清除是什么意思?我们不希望我们绘制的内容被清除。

标签: cwindowswinapiwm-paint

解决方案


WM_PAINT消息是按需生成的(请参阅Paint messages will come in as fast as you let them)。对于每个窗口,系统维护一个更新区域。客户可以将窗口客户区的部分或全部标记为“无效”,调用InvalidateRectInvalidateRgn. 任何一个都添加到更新区域,但不会立即触发WM_PAINT消息。

当系统确定是时候发送WM_PAINT消息时,客户端有责任在完成绘制后清空更新区域,以便WM_PAINT在更新区域再次非空之前不会生成其他消息。

调用为您执行此操作,因此只要您使用标准处理BeginPaint,您就不必担心这一点。WM_PAINT如果您确实有更具体的要求(例如,使用 Direct2D 渲染目标时),您将不得不通过调用ValidateRect或手动清除更新区域ValidateRgn


推荐阅读