Управление вкладками без мерцания с WS_EX_COMPOSITED - PullRequest
2 голосов
/ 15 ноября 2010

У меня есть приложение VS2008 C ++ для Windows XP SP3, разработанное с использованием WTL 8.1. Мое приложение содержит элемент управления вкладкой, который мигает при изменении размера границы приложения.

Моя иерархия окон выглядит следующим образом:

CFrameWindowImpl   CMainFrm
|-CSplitterWindow  Splitter
  |-CTabView       Configuration Tabs
  | |-CDialogImpl  Configuration View 1
  | |-CDialogImpl  Configuration View 2
  | |-CDialogImpl  Configuration View 3
  |-CDialogImpl    Control View

Решение, которое я пытаюсь сделать, - заставить производный класс CFrameWindowImpl использовать стиль WS_EX_COMPOSITED, а все окна под ним - стиль WS_EX_TRANSPARENT. К сожалению, это приводит к тому, что кнопки управления вкладками отображаются в виде пустой черной полосы, а элементы управления любого представления конфигурации вообще не отображаются.

Если я удаляю стили WS_EX_COMPOSITED и WS_EX_TRANSPARENT, форма отображается правильно, но CTabView и все, что под ним, мерцает при изменении размера.

Что мне нужно изменить, чтобы устранить мерцание и правильно нарисовать элементы управления?

Спасибо, PaulH


Edit: Получил это работает. Я удалил все стили WS_EX_TRANSPARENT согласно предложению Марка Рэнсома. Я поставил стиль WS_EX_COMPOSITED на только CTabCtrl (содержится в CTabView). Другие элементы управления получают двойную буферизацию по мере необходимости через WTL::CDoubleBufferImpl<>.

Ответы [ 3 ]

2 голосов
/ 15 ноября 2010

Что не упомянуто в MSDN, так это то, что менеджер окон рабочего стола - компонент, который перехватывает рисование окон в Windows Vista и 7 для выполнения композиции рабочего стола, необходимой для получения эффекта аэростекла, - НЕ реализует WS_EX_COMPOSITED.

Это означает, что вся работа, которую вы вкладываете в то, чтобы этот стиль работал на XP, обречена стать неуместной в Vista или более поздней версии.

Другая проблема с WS_EX_COMPOSITED - и почему это был необязательный стиль, а не по умолчанию в XP: двойная буферизация только берет рисование, выполненное во время блока BeginPaint / EndPaint родительского окна. Множество, даже стандартные элементы управления, выполняют рисование вне своих обработчиков WM_PAINT, и в результате буфер резервного копирования окрашивается только частично.

К сожалению, в результате единственный способ «устранить» мерцание в нативных приложениях API - попытаться минимизировать его: WS_CLIPCHILDREN и WS_CLIPSIBLINGS могут помочь, если у вас нет перекрывающихся элементов управления - чтобы гарантировать, что область каждого элемента управления закрашивается только один раз. , И убедитесь, что главное диалоговое окно не выполняет заливку в WM_ERASEBKGND

2 голосов
/ 15 ноября 2010

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

Похоже, что WS_EX_COMPOSITED автоматически обработает двойную буферизацию, но вам все еще, вероятно, потребуется использовать кисть и / или дескриптор NULL для фона.сообщение WM_ERASEBKGND.

0 голосов
/ 15 ноября 2010

По моему опыту невозможно использовать двойную буферизацию для всего, что содержит дочерние элементы управления (если они все полностью не поддерживают WM_PRINT, а большинство из них не поддерживают).

...