Имитация акрила в приложении Win32

Microsoft недавно анонсировала акриловый материал, похожий на стекло в Fluent Design. Он представлен только в формате XAML / UWP, но выглядит очень похоже на стекло, за исключением того, что он может быть произвольно окрашен и может применяться в приложении к элементам управления пролетом, а также к отдельным окнам приложения.

"Рецепт" заставляет его выглядеть так, как будто он реализован в самом XAML, не подвергаясь воздействию более широкой системы.

Рецепт Microsoft для изготовления акрила: фон, синий, купаж, оттенок, шум

Соответствующий вопрос 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

Другие вопросы по тегам