Win32 - 无法使用 RedrawWindow() 触发 WM_PAINT 消息

Posted

技术标签:

【中文标题】Win32 - 无法使用 RedrawWindow() 触发 WM_PAINT 消息【英文标题】:Win32 - cannot trigger WM_PAINT message with RedrawWindow() 【发布时间】:2014-04-07 11:44:40 【问题描述】:

我正在尝试从 WM_TIMER 触发 WM_PAINT 消息;计时器工作,但 RedrawWindow() 函数似乎没有做任何事情。我做错了什么?

这是我的回调函数:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    PAINTSTRUCT Ps;
    COLORREF    clrBlue = RGB(25, 55, 200);
    RECT        Recto =  20, 28, 188, 128 ;
    COLORREF    clrAqua = RGB(128, 255, 255);
    COLORREF clrRed  = RGB(255, 25, 5);
    static bool x = true;
    switch (message)
    
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        

        break;
    case WM_TIMER:
        //InvalidateRect(hWnd ,NULL , FALSE);
        //RedrawWindow(hWnd , NULL , NULL , RDW_INVALIDATE);
        RedrawWindow(hWnd,NULL,NULL,RDW_INTERNALPAINT);
        break;
    case WM_PAINT:
        if(x)
        
            hdc = BeginPaint(hWnd, &ps);
            SetTextColor(hdc, clrRed);
            TextOut(hdc, 50, 42, L"Some text", 13);
            EndPaint(hWnd, &ps);
            toggle(x);
        
        else
        
            hdc = BeginPaint(hWnd, &ps);
            SetTextColor(hdc, clrRed);
            TextOut(hdc, 50, 42, L"Another text", 13);
            EndPaint(hWnd, &ps);
            toggle(x);
        
        break;
    case WM_DESTROY:
        PostQuitMessage(0);

        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    
    return 0;

【问题讨论】:

如果您想立即重绘,那么还可以尝试在您的RDW_INVALIDATE 旁边添加RDW_UPDATENOW 和/或RDW_ERASENOW 标志。顺便说一句,您的 WM_PAINT 处理程序是否作为您的 RedrawWindow 调用的结果执行? 13 不是您的 TextOut 调用中正确的字符数,这可能会导致未定义的行为。 InvalidateRect 就足够了。确保您的计时器实际被触发,并确保您的计时器间隔足够慢以让重绘实际发生。 【参考方案1】:

由于x 在您的函数中被定义为一个局部变量,所以在调用该函数时它总是得到true 的值。也就是说,WM_PAINT 中的代码永远不会到达ifelse 分支。

例如,尝试将 x 的定义更改为 static bool x = true; 以进行切换工作。

此外,您需要使窗口的内容无效才能重绘:

RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE | RDW_INTERNALPAINT);

【讨论】:

我做了,什么也没发生 您还需要使窗口无效 - 请参阅更新后的答案。 同时传递 RDW_INVALIDATE 和 RDW_INTERNALPAINT 似乎是多余的。

以上是关于Win32 - 无法使用 RedrawWindow() 触发 WM_PAINT 消息的主要内容,如果未能解决你的问题,请参考以下文章

c++: RedrawWindow() 闪烁

无法使用 Win32::GuiTest 发送 shift-end

无法加载 pywin32 库 win32gui

Win32_LogicalMemoryConfiguration在win7下无法使用

Win32:是啥让我的消息循环在该示例中无法正常工作?

Visual C++ 中的刷新窗口