Поведение WS_CLIPCHILDREN и InvalidateRect в Windows 7 - PullRequest
3 голосов
/ 16 декабря 2009

Чтобы уменьшить мерцание, я создаю родительские окна, используя флаг WS_CLIPCHILDREN, и вызываю InvalidateRect во время события WM_SIZE. Этот подход хорошо работал в Windows XP. Тем не менее, я недавно начал программировать на Windows 7, и теперь у меня возникают проблемы с рендерингом при изменении размеров окон. При изменении размера окна его содержимое не обновляется до тех пор, пока я не сделаю что-то, что вызывает перерисовку, например сворачивание и восстановление окна.

Я попытался выполнить InvalidateRect с помощью вызова UpdateWindow, но безрезультатно.

Кто-нибудь знает, как это правильно сделать?

Обновление
Я нашел обходной путь: звонить 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 ]

2 голосов
/ 17 июля 2012

У меня была похожая проблема. Я посмотрел на это решение, но в конце концов я придумал следующее:

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 голосов
/ 16 декабря 2009

Вы можете попробовать позвонить RedrawWindow, передав флаги RDW_INVALIDATE и RDW_ALLCHILDREN.

Редактировать

Чтобы перерисовать фон, вы можете добавить RDW_ERASE. Если вы хотите перерисовать фон на родительском, а не на дочерних элементах, вызовите оба RedrawWindow и InvalidateRect(...,TRUE).

0 голосов
/ 16 декабря 2009

Я нашел этот фрагмент где-то недавно, когда просматривал что-то другое - и он указал, что, удалив CS_VREDRAW и CS_HREDRAW из WNDCLASS для вашего окна, это это уменьшит артефакты, создаваемые при изменении размера окна.

Я использую следующий фрагмент для достижения этой цели, хотя я не могу сказать, какое реальное влияние я на самом деле заметил:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...