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

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

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

Как может Я делаю диалог без мерцания при изменении размера? Я подозреваю, что двойная буферизация должна играть определенную роль, но я не уверен, как это сделать с диалогом с дочерними элементами управления (без создания всех дочерних элементов управления owner-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);

6 ответов


предполагая, что" 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.