Как избежать мерцания при обработке WM_ERASEBKGND в диалоге Windows

StackOverflow https://stackoverflow.com/questions/164751

Вопрос

У меня есть диалог, который изменяет размеры. Он также имеет собственный фон, который я рисую в ответ на вызов WM_ERASEBKGND (в настоящее время это простой вызов FillSolidRect).

При изменении размера диалогового окна происходит огромное мерцание. Чтобы попытаться уменьшить мерцание, я перечисляю все дочерние окна и добавляю их в область отсечения. Это, кажется, немного помогает - теперь мерцание в основном проявляется во всех дочерних элементах управления, когда они перекрашиваются.

Как сделать диалоговое окно без мерцания при изменении размера? Я подозреваю, что двойная буферизация должна сыграть свою роль, но я не уверен, как это сделать с помощью диалогового окна с дочерними элементами управления (без создания всех дочерних элементов управления-draw или что-то в этом роде).

Я должен отметить, что я использую C ++ (не .NET) и MFC, хотя приветствуются только решения на основе Win32:)

ПРИМЕЧАНИЕ. Я попробовал одну вещь, но она не сработала (не знаю почему):

CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.FillSolidRect(rect, backgroundColor);

pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
Это было полезно?

Решение

Предполагая, что " FillSolidRect " стереть фон, а затем вернуть TRUE из WM_ERASEBKGND.

Чтобы выполнить двойную буферизацию, которую вы почти делаете в своем фрагменте кода, вам нужно использовать CreateCompatibleBitmap и выбрать его в свой memDC.

Другие советы

Попробуйте добавить следующую строку в функцию OnInitDialog:

    ModifyStyle(0, WS_CLIPCHILDREN, 0);

Ничего не предпринимайте при обработке WM_ERASEBKGND и стирайте как часть основного WM_PAINT. Вы можете рисовать умнее, чтобы перерисовывать только недопустимые области, или, проще, дважды буферизовать рисунок.

Ничего не делая в фоновом режиме удаления, у вас есть весь код для рисования в одном месте, чтобы другим было легче следить за ним и поддерживать его.

Если вы ориентируетесь на WinXP или выше, вы также можете использовать стиль WS_EX_COMPOSITED, чтобы включить двойную буферизацию по умолчанию для окон верхнего уровня с этим стилем. Имейте в виду, что у этого есть свой набор ограничений - в частности, больше не нужно извлекать циклы OnPaint, используя GetDC и т. Д.

вы можете установить параметр вашего вызова для метода InvalidateRect как false. Это предотвратит отправку WM_ERASEBKGND, когда окно будет перерисовано. Здесь - это хорошая ссылка для предотвращения мерцания в окне.

Двойная буферизация - действительно единственный способ заставить эту работу.

Дочерние элементы управления будут заботиться о себе, пока вы убедитесь, что CLIPCHILDREN .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top