Переключение композиции DWM приводит к тому, что клиентская область теряет альфа
У меня есть простое приложение для Windows здесь:
http://www.bengoodger.com/software/chrome/dwm/app.cc
Мое приложение предоставляет настраиваемую стеклянную рамку для случаев, когда DWM-композитинг активен, и полностью настраиваемую рамку, когда она неактивна или недоступна.
"Настраиваемая стеклянная рамка" состоит из увеличенной области строки заголовка, о которой сообщает моя реализация WM_
NCCALCSIZE, чтобы быть частью клиентской области, так как я хотел бы сделать прозрачные элементы управления в нее. Чтобы эта "высокая область строки заголовка" моего окна была прозрачной, я заполняю ее прозрачным черным (BLACK_BRUSH в простом примере выше), который заставляет DWM рисовать его как стекло.
Когда системный DWM переключается, например, с помощью панели управления "Параметры внешнего вида" для переключения на Vista Basic или Windows Standard, или когда запускается приложение, требующее отключение DWM системой, мое приложение переключается в полностью настраиваемый режим рендеринга путем обработки WM_NCPAINT и т. Д. Когда я переключаюсь назад, я ожидаю обратного, что в основном происходит, за исключением того, что моя "высокая область заголовка" теперь полностью черная.
Я обнаружил, что могу обойти эту проблему, получив расположение окна, скрывая окно и затем снова устанавливая расположение окна в моей обработке WM_DWMCOMPOSITIONCHANGED, но это вызывает другие ужасные ошибки (наименьшее из которых - это изменение z-порядка окна).
У меня вопрос - что я тут не так делаю? Кажется, что окно каким-то образом вводится в поддельное состояние, и его скрытие / показ исправляет его. Как я могу предотвратить это? Любое руководство будет с благодарностью.
Примечание: я несколько сузил это. При использовании стекла DWM любая часть клиентской области, окрашенная в черный цвет и отображаемая поверх клиентской области, отображается прозрачной. Мы заметили, что при возврате в Glass из non-Glass клиентская область отображается сплошным черным вместо прозрачного. Однако, когда окно развернуто и затем восстановлено, оно снова становится прозрачным. Когда я впоследствии перетаскиваю размер окна меньше, окно верхней части остается прозрачным. Когда я перетаскиваю его больше, верхняя часть окна снова становится черной. Как будто DWM кеширует пиксели за окном, а увеличение размера окна приводит к тому, что он не может ничего там рисовать, потому что его кэш недостаточно велик. Я не могу найти функцию DWM для сброса этого состояния. Кажется, что "Развернуть / Свернуть", а затем "Восстановить" или "SetWindowPlacement" способны щекотать его, но имеют и другие нежелательные побочные эффекты.
1 ответ
http://www.codeproject.com/KB/dialog/rtaGlassEffectLib.aspx
Как вы, возможно, заметили, свойство GlassEnabled отлично подходит для тестирования, если эта функция включена вашей системой, а затем начните использовать нашу библиотеку и вызовите функцию ShowEffect() для отображения эффекта стекла. Теперь предположим, что пользователь отключил / включил Aero Theme во время работы вашего приложения! Это может вызвать проблемы с внешним видом вашего приложения.
Чтобы решить эту проблему, в библиотеку были добавлены два события для отслеживания изменений, происходящих в системе во время работы приложения. Это два события: GlassEffectEnabled и GlassEffectDisabled.
Теперь для людей, которым нравится знать, как все работает. Я могу сказать, что эти события были реализованы путем мониторинга сообщений, поступающих из системы в окна нашего приложения, в поисках сообщения WM_SYSCOLORCHANGE, которое указывает, что системные цвета были изменены. Поэтому, сделав быстрое сравнение между состоянием свойства GlassEnabled до и после этого сообщения, мы можем решить, была ли эта функция включена или нет.