win32-gdi 系统驱动 WM_PAINT 无闪烁吗?

问题描述

运行此代码会导致标题问题:

如果您调整窗口大小,您将看不到任何闪烁(系统发送的重绘)

如果在窗口内移动鼠标,会出现严重闪烁(我发的repaint)

如何重现系统驱动的WM_PAINT?

#include <windows.h>
#include <wingdi.h>

LRESULT CALLBACK proc(HWND hwnd,UINT msg,WParaM wparam,LParaM lparam)
{
    switch(msg)
    {
        case WM_ERASEBKGND: return true;break;
        case WM_MOUSEMOVE: InvalidateRect(hwnd,0); break;
        case WM_PAINT:
        {
            InvalidateRect(hwnd,0);
            HBrush b= CreateSolidBrush(0x000000ff);
            HBrush c= CreateSolidBrush(0x0000ff00);
            HBrush d= CreateSolidBrush(0x00ff0000);
            RECT r;
            GetClientRect(hwnd,&r);
            PAINTSTRUCT ps;
            HDC hdc=BeginPaint(hwnd,&ps);
            FillRect(hdc,&r,b); 
            Sleep(10);
            FillRect(hdc,c);
`           Sleep(10);
            FillRect(hdc,d);
            EndPaint(hwnd,&ps);
            DeleteObject(b);
            DeleteObject(c);
            DeleteObject(d);
        }
        break;
        default:
            return DefWindowProc(hwnd,msg,wparam,lparam);
    }
    return 0;
}
int main()
{
    HWND hwnd=CreateWindow(WC_DIALOG,WS_OVERLAPPEDWINDOW|WS_VISIBLE,500,0);
    SetwindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)proc);
    
    MSG msg;
    
    while (true)
    {
        if (GetMessage(&msg,0) != WM_CLOSE)
        {
            TranslateMessage(&msg);
            dispatchMessage(&msg);
        }
    }
    return 1;
}

解决方法

如果鼠标只在窗口上移动,则不应使窗口无效,因为这最终会导致 WM_PAINT 消息。这会导致闪烁(与睡眠相结合)。