Правильный способ сделать прозрачные кнопки в WINAPI - PullRequest
3 голосов
/ 04 января 2011

Пытался зайти в Google, но не смог найти окончательный ответ.

Как сделать кнопку с переопределенной WM_PAINT прозрачной.Чтобы вы могли видеть форму через нее во всех местах, кроме тех, где что-то нарисовано.В то же время, избегая мерцания.

Я видел примеры с SetBkMode (HDC, TRANSPARENT), используя NULL_BRUSH, примеры с CompatibleDC и BitBlts, но я не совсем уверен, какой путь правильный, итакже, как это ведет себя, когда WM_CLIPCHILDREN установлен в родительском окне.В большинстве экспериментов, которые я проводил, тоже было странное поведение.Не могу найти хорошую документацию по внутренним связям WM_ERASEBKGND / WM_CTLCOLOR / WM_PAINT / WS_EX_COMPOSITED / WS_CLIPCHILDREN / etc на MSDN.

Кто-нибудь знает, где я мог прочитать об этой теме со всеми связанными уловками?

1 Ответ

6 голосов
/ 04 января 2011

ммм, я никогда не находил ничего похожего на авторитетный документ по этой теме.

Это просто мой довольно случайный дамп памяти, пытающийся получить элементы управления для "хорошей игры" при анимации наокно, которое было скином (обычная не-клиентская область с растровым фоном), слоистым (чтобы получить окно с пользовательскими не-клиентскими краями с эффектами тени) или с расширенными эффектами Aero Glass (через DwmExtendFrameIntoClient).

  • SetBKMode (... TRANSPARENT) просто гарантирует, что рендеринг текста не заполняет фон текста текущим цветом bk.
  • WS_EX_COMPOSITED заставляет окна закрашивать родительский и все дочерние окна назадбуфер, когда родитель недействительным, а затем закрасить обратный буфер.Это без мерцания, но NT 6.0 представила менеджер окон рабочего стола, который не поддерживает WS_EX_COMPOSITED.
  • WS_CLIPCHILDREN не позволяет дочерним окнам и родительскому окну рисовать одну и ту же область дважды.Но противопоказано, если вам нужно использовать групповые блоки или элементы управления вкладками.
  • WS_CLIPSIBLING могут быть полезны, если дочерние окна перекрываются и вызывают мерцание.опять же, этот стиль бесполезен, если вам нужно использовать групповые блоки или элементы управления вкладками.
  • Другая проблема с WS_CLIPCHILDREN заключается в том, что вы не можете нарисовать фон в родительском режиме окна widnows и использовать кисть NULL, чтобы открытькожа.Вы можете вернуть кисть из сообщений WM_CTLCOLORxxx, чтобы заставить некоторые стандартные элементы управления рисовать их фон с помощью растрового изображения кожи.
  • WS_EX_LAYERED - это другой стиль, который заставляет окна буферизовать рисование вашего родительского окна.Но многоуровневая программа рисования окон вообще не рисует дочерние окна, поэтому вам нужно вручную рисовать дочерние окна, отправляя сообщения WM_PRINTCLIENT.Не все элементы управления поддерживают это сообщение.
  • WPF решает проблему отсутствия буферизованного рисования и поддержки альфа-канала, вообще не создавая фактические дочерние окна для своих кнопок.

Окончательное решениеситуация:

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

Если вы используете Групповые блоки или TabControls для создания рамок других элементов управления, вы обязательно должны получить правильный Z-порядок при использовании WS_CLIPSIBLINGS.

Отправляя элементы управленияСообщения WM_PRINTCLIENT и некоторые подклассы позволяют получить стандартные элементы управления для рисования на DIBSection, который затем можно вручную (или использовать рабочие функции DWM) восстановить альфа-канал, а затем нарисовать в многослойном окне или в окне с расширенным аэростакан.Это даже без мерцания, но элементы управления, которые не поддерживают WM_PRINTCLIENT или часто обновляются вне WM_PAINT, не будут отображаться правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...