Как в этом случае использовать двойной буфер?

Скажем, у меня есть три элемента управления A, B, C. Все они унаследованы от CDialog, A - главный диалог, A содержит B, а B содержит C., и каждый раз, когда я использую перетаскивание мышью C, B и C будут перемещаться вместе .

Это изображение: http://img507.imageshack.us/img507/7039/31709956.jpg

Мы знаем, что это заставит B и C перерисовать себя. и это может вызвать мерцание.

И мой вопрос: нет ли способа удвоить буферизацию этих двух диалогов B и C?

Я знаю, что в XP и Vista есть атрибут WS_EX_COMPOSITED, который поможет, но я не хочу его использовать.

кто-то может предложить мне использовать memDC, но моя проблема в том, как я могу объединить действия в функции ondraw B и ondraw C в буфер?

Надеюсь, кто-нибудь знает, что я сказал.

Заранее спасибо!


person MemoryLeak    schedule 27.09.2009    source источник
comment
когда вы говорите: диалог ... вы имеете в виду, что это отдельные окна? (так что CDialog?)   -  person Toad    schedule 27.09.2009
comment
да, все диалоги унаследованы от CDialog ~   -  person MemoryLeak    schedule 27.09.2009


Ответы (5)


что очень помогает мерцанию, так это перегрузка метода erasebackground. Этот метод заполняет весь фон сплошным цветом. Краска затем раскрашивает все предметы на ней. Если удалить фон для стирания, краска просто закрасит то, что уже есть, устраняя мерцание.

person Toad    schedule 27.09.2009
comment
но моя проблема в том, как я могу объединить действия в функции ondraw B и ondraw C в буфер? скажем, когда я перетаскиваю C, B и C будут перерисованы, последовательность - сначала отрисовка B, а затем C, она была завершена в их собственной функции ondraw, и я хочу дважды буферизовать их в растровое изображение, а затем рисовать его поверх А. Но я не знаю, как это сделать. - person MemoryLeak; 27.09.2009
comment
Я не могу представить, чтобы 2 отдельных окна можно было перерисовать с помощью 1 внеэкранного растрового изображения. Для этого вам нужно, чтобы диалоги были чем-то другим, а не отдельными окнами. - person Toad; 27.09.2009
comment
привет ... Я только что видел ваше тестовое изображение. Действительно ли диалоги полностью нарисованы вами (так что на нем нет элементов управления?) В таком случае, зачем вообще возиться с CDialog и просто не рисовать их непосредственно в главном окне самостоятельно, тем самым устраняя мерцание. - person Toad; 27.09.2009
comment
так как я добавлю некоторый обработчик событий в дочерний диалог C, например перетаскивание - person MemoryLeak; 27.09.2009
comment
WS_EX_COMPOSITED, этот атрибут может помещать все свои дочерние элементы в буфер, а затем рисовать их. но я не хочу использовать это .... - person MemoryLeak; 27.09.2009
comment
даже если вы хотите обрабатывать перетаскивание, вы можете сделать это в родительском окне, и в зависимости от того, находится ли мышь над одним из клиентов, она будет выполнять различные действия при перетаскивании. Раньше я создавал системы с графическим интерфейсом, которые запускались бы в одном окне, в котором отсутствовали мерцания, обрабатывались перетаскивания и т. Д. Я думаю, поскольку у вас нет элементов управления Windows на ваших cdialogs, а только контент, созданный пользователем, таким образом может быть гораздо более подходящий - person Toad; 27.09.2009
comment
не могли бы вы загрузить исходный код с rapidshare.com/files/283950611/TestProject.7z.html, и поискать меня? спасибо ~~ Я действительно перепробовал все методы, но не удалось ... - person MemoryLeak; 27.09.2009

CS_PARENTDC поможет.

person Lixiang Xie    schedule 27.09.2009

Я никогда не связывался с вызовами рисования Windows с двойной буферизацией, но однажды я наткнулся на обсуждение этого вопроса на форуме Microsoft: http://social.msdn.microsoft.com/forums/en-США/vcgeneral/thread/789a4116-d3b2-488e-801a-3f7bc1e4d33a/ Возможно, это будет вам полезно.

person TheUndeadFish    schedule 27.09.2009

Предполагая, что B и C являются потомками A (обычный случай для диалогов), A должен иметь установленный стиль WS_CLIPCHILDREN. Если вместо этого B и C являются братьями и сестрами A, установите для A бит WS_CLIPSIBLINGS.

person Jerry Coffin    schedule 28.09.2009

Возьмите один MemDC для основного диалогового окна A и комбинированный MemDC для B и C.Теперь, когда вы перетаскиваете C, вы должны объединить эти 2 MemDC в зависимости от текущей позиции с помощью функции BitBlt, а затем, наконец, вам нужно выполнить bitblt комбинированного memDC на фактическом DC диалога.

Наряду с этим вы должны переопределить метод onerasebackground, чтобы мерцания не было.

person Ashish    schedule 23.10.2009