Акриловый материал в приложении win32
Microsoft недавно представила свой новый "свободный" дизайн языка, и одной из его частей является "акриловый" материал. Этот эффект делает элемент прозрачным и размывает фон. Он может быть применен либо к окну, так что части нижних окон светятся (фоновый акрил), либо к отдельным элементам в окне, так что другие элементы управления просвечивают (акрил в приложении). Концептуально и визуально очень похоже на вибрации на macOS.
Он реализован как специальная кисть в XAML, но мне интересно, есть ли способ использовать ее (фоновый акрил) в обычном приложении Win32? Эффект выглядит очень похоже на размытие, примененное к меню "Пуск" и панели задач (которое обрабатывается SetWindowCompositionAttribute), что заставляет меня поверить, что его можно активировать с помощью аналогичного флага.
Вопрос: интересно, как это реализовано? Это просто флаг, который можно установить в окне, а затем применить в DWM (например, SetWindowCompositionAttribute или Aero Glass в Vista и 7)? Или UWP имеет какой-то контроль над DWM и может настроить шейдеры для управления его рендерингом? Под Vista, когда DWM был впервые представлен, у него был общий код с WPF, и он фактически разделял (DirectX-подобные) буферы и граф сцены, поэтому подобные трюки были возможны. Утилита magifier может увеличивать приложения WPF резко, как векторные изображения, но эта функциональность была утеряна позже. То, как MS представляет "акрил" на этой странице (в виде разных слоев и реализовано в виде кисти XAML), заставляет меня думать, что вам как-то придется внедрять слои в DWM-сцену, что затруднит или сделает невозможным использование с Win32.
4 ответа
Sciter 4.2 добавляет поддержку акриловых фонов (на Windows и MacOS):
Акриловая тема и элементы управления UWP (в стиле CSS) в Sciter:
Демо-браузер uSciter, Windows:
Демо-браузер uSciter, MacOS:
Sciter на Windows - это обычное приложение Win32 (не UWP).
Чтобы сделать это размытие, он делает следующее:
Создает окно с WS_EX_NOREDIRECTIONBITMAP
бывший флаг.
вызовы:
struct WINDOWCOMPOSITIONATTRIBDATA {
WINDOWCOMPOSITIONATTRIB dwAttrib;
PVOID pvData;
SIZE_T cbData;
};
enum ACCENT_STATE {
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_ENABLE_ACRYLIC_BLURBEHIND = 4,
ACCENT_INVALID_STATE = 5
};
ACCENT_POLICY accent = { ACCENT_ENABLE_ACRYLIC_BLURBEHIND, 0, clr, 0 };
WINDOWCOMPOSITIONATTRIBDATA data;
data.dwAttrib = WCA_ACCENT_POLICY;
data.pvData = &accent;
data.cbData = sizeof(accent);
SetWindowCompositionAttribute(get_hwnd(), &data);
Где clr - AGBR, что-то вроде 0xCC000000
для темного размытия за фоном.
Рендеринг контента с использованием поверхности Direct2D, установленной в DirectComposition Visual, прикрепленной к цепочке подкачки окна, используя IDXGIFactory2::CreateSwapChainForComposition
Детали всего этого немного мутные и COM-многословные, вздох (я автор Sciter).
По крайней мере, вы должны использовать Direct2D для рисования, чтобы сделать что-то подобное.
Я только что нашел этот проект, который приносит акрил в WPF: https://github.com/bbougot/AcrylicWPF
Кажется, ваша гипотеза была хорошей. Он использует SetWindowsCompositionAttribute и применяет к нему шейдер.
Acrylic Effect Sciter использует SetWindowCompositionAttribute(), в настоящее время он медленный, но я придумал другой способ реализовать тот же акриловый эффект, но другой метод.
Посмотрите этот акриловый эффект Win32 с использованием IDComposition и Direct2D
Его эффекты создаются с помощью API-интерфейсов XAML более низкого уровня, в которых используется XAML-композитор UWP, поэтому я бы сказал, что сомневаюсь, что вы сможете достичь этого изначально в Win32. Если вы действительно этого хотите, вы можете либо перенести свое приложение через Desktop Bridge и преобразовать пользовательский интерфейс, либо имитировать эффекты с помощью технологии, доступной сегодня. (Браузеры, такие как Chrome, могут использовать Window Chrome в своем приложении, хотя я не уверен, как вы достигнете акрилового эффекта).