Win32: Как сделать пометку тени непрямоугольной? Слоеное окно?
я создал многоуровневое окно, добавив расширенный стиль WS_EX_LAYERED:
wndClass.ExStyle = wndClass.ExStyle | WS_EX_LAYERED;
Windows будет использовать черный в качестве значения цвета хроматического ключа. Я собираюсь оставить большую черную границу, чтобы сделать проблему очевидной:
![alt text]()
После того, как окно построено, я говорю ему использовать черный в качестве цвета хроматического ключа:
SetLayeredWindowAttributes(hwnd, 0x00000000, 255, LWA_COLORKEY);
Теперь всплывающее многослойное окно выглядит частично прозрачным:
![alt text]()
Проблема - последний шаг. я хочу использовать стиль класса CS_DROPSHADOW, доступный начиная с Windows XP, для создания тени:
wndClass.Style = wndClass.Style | CS_DROPSHADOW;
Появляется тень, но тень окружает исходное прямоугольное окно и не учитывает прозрачность окна, обеспечиваемую многослойным окном:
![CrLH6.png]()
Кто-нибудь знает, какую магическую опцию я пропустил где-нибудь, чтобы заставить тень отбрасывать непрямоугольное многослойное окно?
Еще один пример возникновения этой проблемы - это когда вы не добавляете отступы 6px/margin. Окно подсказок, нарисованное темами Windows®, не прямоугольное. Это оставляет небольшой видимый промежуток, где окно прозрачно, но тень не появляется:
![alt text]()
Microsoft удалось заставить его работать, как вы можете видеть из подсказки Internet Explorer:
![alt text]()
Присмотревшись ближе к окну tooltips
класса tooltips
Windows. Используя SpyXX - я могу получить прямоугольник окна и стили классов:
![]()
SpyXX говорит:
Rectangle: (440, 229)-(544, 249), 104x20
Restored Rect: (440, 229)-(544, 249), 104x20
Client Rect: (0, 0)-(104, 20), 104x20
Таким образом, все указывает на то, что само окно имеет размер 104х20 пикселей, а тень находится за пределами самого окна. (Что соответствует CS_DROPSHADOW
.)
Далее я могу взглянуть на стили класса окна tooltips
:
Windows Styles: 94000001
WS_POPUP 80000000
WS_VISIBLE 10000000
WS_CLIPSIBLINGS 4000000
TTS_ALWAYSTIP 1
Extended Styles: 00080088
WS_EX_LAYERED 80000
WS_EX_TOOLWIN 80
WS_EX_TOPMOST 8
Интересно, что он не использует CS_SAVEBITS
(0x800
); что полезно для небольших, недолговечных окон.
Он также не использует CS_DROPSHADOW
(0x20000
). Так что теперь мне интересно, как он рисует за пределами своего собственного окна?
Примечание. Прозрачные многослойные окна задокументированы как предпочтительный метод по сравнению с регионами.
Изменить: Многоуровневая Windows была с Windows 2000. CS_DropShadow был добавлен с XP.
Ответы
Ответ 1
Прозрачные слоистые окна документируются как предпочтительная техника по регионам.
Однако CS_DROPSHADOW
обращает внимание на регионы. Если вы обрезаете или иным образом формируете свое окно с помощью региона, тень будет следовать за новым контуром.
К счастью, вы можете использовать регионы со слоистыми окнами, и, объединив их, получите эффект, который вы ищете.
BTW: tooltips_class32 использует CS_DROPSHADOW - вы не увидите его в стилях окна, потому что это стиль класса, а не стиль окна.
Ответ 2
Почему вы не используете LWA_ALPHA и не создаете тень в изображении?
Отредактируйте ответ в ответ:
A) Не останавливает использование альфа-канала PNG только для тени. Blt 2 изображения вместе и использовать как одно изображение.
B) Не сложно создать тени. На изображении вы разместили свой черный цвет с тремя различными значениями альфа.
C) Но это не работает? т.е. время для творчества.
D) Тогда не пытайтесь заставить окна делать что-то, что вам не поможет.
E) Совершенно не имеет значения. Слоистые окна обрабатывают это для вас.
Я настоятельно рекомендую вам узнать больше о многоуровневых окнах, потому что они МОГУТ помочь вам в достижении своей цели.
Edit2: У вас есть растровое изображение. Его довольно легко сканировать по изображению и найти, какие биты будут иметь цветную клавиатуру (путем идентификации самого черного), и курица модифицирует это, чтобы иметь альфа 0, где все остальное будет иметь альфа 255 (Not: Возможно, вам придется преобразовать изображение на 32-битное изображение из более низкого цветового формата, вы можете сделать это, создав новый DC и скопировав изображение). Это даст вам тот же эффект с LWA_ALPHA, что и с LWA_COLORKEY. Оттуда довольно легко определить пиксель на краю, где цвет меняется на (R = 0, G = 0, B = 0, A = 0). Затем вы меняете этот первый пиксель на n альфа 192, один - на 128, а один ниже - на 64. Теперь у вас есть альфа-градация ниже изображения, которое будет выглядеть как тень. Вы можете настроить альфа, чтобы получить необходимый эффект.
Ответ 3
CS_DROPSHADOW
работает только со стандартными прямоугольными окнами. Окна WS_EX_LAYERED
не поддерживают все. Они являются более низкоуровневым методом самообслуживания, чтобы нарисовать именно то, что вы хотите.
Чтобы получить тень, вам придется генерировать тень от альфа-канала на изображении.