开发者

Behavior of WS_CLIPCHILDREN and InvalidateRect in Windows 7

开发者 https://www.devze.com 2022-12-13 23:45 出处:网络
To reduce flickering I create my parent windows using the WS_CLIPCHILDREN fl开发者_运维百科ag and I call InvalidateRect during the WM_SIZE event. This approach has worked well in Windows XP. However,

To reduce flickering I create my parent windows using the WS_CLIPCHILDREN fl开发者_运维百科ag and I call InvalidateRect during the WM_SIZE event. This approach has worked well in Windows XP. However, I recently started programming on Windows 7 and I'm now experiencing rendering issues when resizing windows. When resizing a window its contents is not refreshed until I do something that forces a redraw, like minimizing and restoring the window.

I've tried following up the InvalidateRect with a UpdateWindow call but with no effect.

Does anyone know how to do it correctly?

Update

I found a workaround: calling InvalidateRect(childHWND, NULL, FALSE) on all child windows followed by a InvalidateRect(parentHWND, NULL, TRUE) on the parent window fixes the rendering problem without introducing noticeable flickering.

Other suggestions are still welcome!

Update 2

I tried the RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN) but that resulted in some rendering issues (left-over pixels).

Update 3

The RedrawWindow works when followed by a InvalidateRect(hwnd, NULL, TRUE). Thanks @interjay!


You can try calling RedrawWindow, passing flags RDW_INVALIDATE and RDW_ALLCHILDREN.

Edit:

To redraw the background, you can add RDW_ERASE. If you want to redraw the background on the parent but not the children, call both RedrawWindow and InvalidateRect(...,TRUE).


I have had a similar problem. I looked at this solution but finally I came up with the following:

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);
    }
}

I do hope this helps. . .


I found this snippet somewhere recently when browsing for something else - and it indicated that by removing CS_VREDRAW and CS_HREDRAW from the WNDCLASS for your window, that it would reduce the artifacts created when resizing a window.

I use the following snippet to achieve this, though I cannot say how much real impact I have actually noticed it having:

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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消