Как избежать мерцания при обработке WM_ERASEBKGND в диалоге Windows
Вопрос
У меня есть диалог, который изменяет размеры. Он также имеет собственный фон, который я рисую в ответ на вызов 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
.