Windows 7中WS_CLIPCHILDREN和InvalidateRect的行为

时间:2009-12-16 09:42:39

标签: c++ winapi

为了减少闪烁,我使用WS_CLIPCHILDREN标志创建父窗口,并在WM_SIZE事件期间调用InvalidateRect。这种方法在Windows XP中运行良好。但是,我最近开始在Windows 7上编程,现在我在调整窗口大小时遇到​​了渲染问题。调整窗口大小时,在我执行强制重绘的操作之前,其内容不会刷新,例如最小化和恢复窗口。

我尝试使用UpdateWindow调用跟进InvalidateRect但没有效果。

有谁知道如何正确地做到这一点?

更新
我找到了一种解决方法:调用InvalidateRect(childHWND, NULL, FALSE) 在父窗口上跟随InvalidateRect(parentHWND, NULL, TRUE)的所有子窗口上修复渲染问题,而不会引起明显的闪烁。

其他建议仍然欢迎!

更新2
我尝试了RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN),但这导致了一些渲染问题(遗留像素)。

更新3
RedrawWindow后跟InvalidateRect(hwnd, NULL, TRUE)后工作。谢谢@interjay!

3 个答案:

答案 0 :(得分:2)

您可以尝试拨打RedrawWindow,传递标记RDW_INVALIDATERDW_ALLCHILDREN

修改

要重绘背景,可以添加RDW_ERASE。如果您要重新绘制父级而非子级的背景,请同时调用RedrawWindowInvalidateRect(...,TRUE)

答案 1 :(得分:2)

我遇到过类似的问题。 我看了解这个解决方案,但最后我想出了以下内容:

void WindowClass::Invalidate(BOOL bErase)
{
    base::Invalidate(bErase);

    // traverse along all the child windows.
    for (CWnd* pChild = GetWindow(GW_CHILD); pChild != NULL; pChild = pChild->GetWindow(GW_HWNDNEXT))
    {
        // Let them do the invalidate also.
        pChild->Invalidate(bErase);
    }
}

我希望这会有所帮助。 。

答案 2 :(得分:0)

我最近在浏览其他内容时发现了这个片段 - 并且它表明通过从 WNDCLASS 中删除 CS_VREDRAW CS_HREDRAW 窗口,它将减少调整窗口大小时创建的工件。

我使用以下代码段来实现这一点,但我不能说我实际注意到它有多少实际影响:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT & cs)
{
    // do standard thing
    if (!CMFCToolboxMDIFrameWnd::PreCreateWindow(cs))
        return FALSE;

    // ensure a thinner border
    cs.dwExStyle &= ~WS_EX_CLIENTEDGE;

    // avoid repainting when resized by changing the class style
    WNDCLASS wc;
    VERIFY(GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wc));
    cs.lpszClass = AfxRegisterWndClass(0, wc.hCursor, wc.hbrBackground, wc.hIcon);

    return TRUE;
}