Имитация акрила в приложении Win32
Microsoft недавно анонсировала акриловый материал, похожий на стекло в Fluent Design. Он представлен только в формате XAML / UWP, но выглядит очень похоже на стекло, за исключением того, что он может быть произвольно окрашен и может применяться в приложении к элементам управления пролетом, а также к отдельным окнам приложения.
"Рецепт" заставляет его выглядеть так, как будто он реализован в самом XAML, не подвергаясь воздействию более широкой системы.
Соответствующий вопрос SO подтверждает это (он лишен конкретных технических ответов, но подразумевает, что акрил не доступен через WinAPI, как стекло).
Как бы кто-то подражал этому в простом старом приложении Win32? Использование стекла и смешивание? (Какие API-интерфейсы и что возможно в стеклянных API-интерфейсах Win10 Fall Update, которых не было в Win7?) Если приложение было создано с Win32, но использовало поверхность DirectX для рендеринга, открыло бы оно больше возможностей?
4 ответа
Как упоминалось в ответе @zett42, я думаю, что это реализовано с использованием DirectComposition.
Немного истории: с Vista Microsoft представила менеджер окон рабочего стола, DWM, который является механизмом компоновки для рабочего стола. В DWM окна рисуют текстуры, которые затем объединяются в DWM. Преимущества заключаются в том, что вы можете получить необычные эффекты, такие как 3D-анимация, прозрачность и т. Д., И все будет с двойной буферизацией, поэтому вы не получите артефактов рендеринга.
Первоначально DWM был основан на MIL (Media Integration Layer), который, я думаю, был API-интерфейсом для работы со сценой. Интересно, что WPF, который был представлен в то время, также использовал MIL. Это было действительно круто, потому что DWM мог видеть граф сцены окна WPF, и когда это оказывало бы влияние, такое как масштабирование окна, он видел бы его как векторы, а не как растровое изображение, поэтому он мог масштабировать его без артефактов. Однако в какой-то момент Microsoft развила версию MIL, используемую в WPF, и эта интеграция была потеряна.
Перенесемся на несколько лет назад в Windows 8. Microsoft представила новые приложения "Metro" (позже "Modern", а теперь "UWP"). В этих современных приложениях используется новый API для композиции - DirectComposition. Этот API также доступен для приложений Win32 и теперь используется самим DWM. Если вы посмотрите на общедоступные функции DWM, то некоторые из них, связанные с MIL, устарели, поэтому он поддерживает мою теорию о том, что MS перешла от MIL к DC. Теперь, когда мы снова находимся в исходной ситуации, когда приложения и DWM используют одну и ту же инфраструктуру, мы можем легко добавить некоторые интересные эффекты.
В какой-то момент MS представила новые эффекты смешивания в DirectComposition, предоставляемые интерфейсом IDCompositionDevice3. Среди них эффект размытия Гауссана, а также шум, оттенок и другие необходимые эффекты. Я нашел способ применить эти эффекты в моем окне, но я не знаю, как применить их к моему окну. К сожалению, у меня нет доступа к моему коду сейчас, я обновлю свой ответ, когда у меня будет.
Я основал свое исследование на статье " Эффективные альфа-смешанные окна: DirectComposition". По сути, у вас есть "Устройство", соответствующее экрану, и "Визуал", соответствующий содержимому вашего окна. Что вы должны изменить это:
- Ваше устройство может создавать эффекты для вас. Запомни
QueryInterface
это кIDCompositionDevice3
, - Затем вы можете позвонить
SetEffect
на вашеIDCompositionVisual3
,
Однако, как я уже сказал, это относится только к содержимому окна. Я думаю, что должен быть секретный API, чтобы получить родительский Visual для текущего окна из DWM, и тогда это должен быть только вопрос вызова SetEffect
на этом Visual, чтобы получить эффект. Если кто-то разбирается в отладчике, можно найти этот API, отследив приложение UWP, использующее эффект Acyllic.
Как снимок в синем, я бы посмотрел на функцию GetWindowCompositionAttribute. Недавно он получил несколько интересных флагов звучания, таких как WCA_VISUAL_OWNER.
Рафаэль Ривера опубликовал небольшое демонстрационное приложение о том, как использовать Acrylic Blur в настольных приложениях начиная с Windows 10 v1803 (сборка 17134.x - RS4 - обновление за апрель 2018 года)
В основном enum AccentState
есть новая запись ACCENT_ENABLE_ACRYLICBLURBEHIND = 4
,
Я думаю, что можно было бы имитировать это с помощью Win32 API или, по крайней мере, создать результат, который близок.
- Размытие и тонировка могут быть достигнуты с использованием недокументированных
SetWindowCompositionAttribute()
, который вы уже связали. Эта функциональность должна предоставляться DWM, что, безусловно, верно даже для реализации XAML. - Я не уверен, что должна делать смесь исключений, по крайней мере из уменьшенных скриншотов на странице MS, это кажется незначительным.
- Текстура шума должна быть простой, поскольку она, вероятно, просто альфа-смешанная... ну... шум. Использовать генератор случайных чисел или, возможно, функцию перлин-шума?
Вы также можете посмотреть на прямую композицию, возможно, в сочетании с WS_EX_NOREDIRECTIONBITMAP
расширенный стиль окна, как описано в статье " Высокопроизводительное наложение окон с помощью Windows Composition Engine ". Я еще не использовал эту технологию, но в статье говорится, что XAML основан на Direct Composition, что должно открыть все возможности.
В последнем устройстве с Windows 10 мы можем комбинировать DWM API и Direct Composition API, чтобы воссоздать акриловый эффект в Win32. В более новых версиях Windows мы можем скопировать содержимое DWM Thumnail в
IDComposition
Визуальный и его можно использовать для воссоздания фона для акрила.
Затем фон можно перенести на
IDCompositionGaussianBlurEffect
чтобы размыть фон.
Вот рабочий пример:эффект акрила Win32