2008-10-02 8 views
9

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

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

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

Я должен отметить, что я использую 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); 

ответ

8

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

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

3

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

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

5

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

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

6

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

ModifyStyle(0, WS_CLIPCHILDREN, 0); 
5

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

4

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