Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Acrylic material in win32 app

Microsoft recently revealed their new "fluent" design langauge, and one part of it is the "acrylic" material. This effect makes an element transparent and blurs the background. It can either be applied to a window, such that parts of underlying windows shine though (background acrylic), or to individual elements in the window, so other controls shine through (in-app acrylic). It is conceptually and visually very similar to vibrancy on macOS.

It is implemented as a special Brush in XAML, but I wonder it there is a way to use it (background acrylic) in a regular Win32 app? The effect looks very similar to the blur applied to start menu and taskbar (which is handled by SetWindowCompositionAttribute) which leads me to believe that it might be activatable by a similar flag.

A subquestion: I wonder how it is implemented? Is it just a flag that you can set on a window, and then applied in the DWM (like SetWindowCompositionAttribute, or like Aero Glass in Vista and 7)? Or does UWP have some kind of control over the DWM, and can set shaders to control how it is rendered? Under Vista, when DWM was first introduced, it had common code with WPF, and it actually shared the (DirectX-like) buffers and scene-graph, so tricks like that were possible. The magifier utility could magnify WPF apps sharply like vector images, but that functionality was lost later. The way MS presents "acrylic" on that page (as different layers, and implemented as an XAML brush), leads me to think that you'd somehow have to inject layers into the DWM scenegraph, which would make it harder or impossible to use from Win32.

like image 341
jdm Avatar asked May 12 '17 07:05

jdm


3 Answers

Sciter 4.2 adds support of acrylic backgrounds (on Windows and MacOS):

Acrylic theme and UWP alike controls (CSS styled) in Sciter:

Acrylic theme and UWP alike controls in Sciter

uSciter demo browser, Windows:

uSciter demo browser, Windows

uSciter demo browser, MacOS:

uSciter demo browser, MacOS

Sciter on Windows is an ordinary Win32 application (not UWP).

In order to render that blurbehind it does the following:

Creates window with WS_EX_NOREDIRECTIONBITMAP ex flag.

Calls:

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);

Where clr is AGBR, something like 0xCC000000 for dark blur behind background.

Renders content using Direct2D surface set on DirectComposition Visual attached to window's swap chain using IDXGIFactory2::CreateSwapChainForComposition

Details of all this are a bit murky and COM-verbose, sigh (I am an author of the Sciter).

At least you shall use Direct2D for drawing in order to render something like this.

like image 100
c-smile Avatar answered Nov 18 '22 06:11

c-smile


I just found this project that bring acrylic to WPF : https://github.com/bbougot/AcrylicWPF

It seems your hypothesis were good. It uses SetWindowsCompositionAttribute and apply a shader on it.

like image 3
Jicay144 Avatar answered Nov 18 '22 07:11

Jicay144


The Acrylic Effect Sciter uses is by using SetWindowCompositionAttribute(),currently it is laggy, but I came up with another way to implement same acrylic effect but a different method.

Check out this Win32 Acrylic Effect using IDComposition and Direct2D

like image 3
trickymind Avatar answered Nov 18 '22 08:11

trickymind