WPF glass without frame and without resizing out of focus

I am trying to create a WPF Aero glass window borderless and without resizing using the DwmEnableBlurBehindWindow method from DmwAPI . However, for some strange reason, the glass color of this window looks as if the window is out of focus. As you can see in the following three images, ordinary windows with borders (for example, Figures 1 and 2) work fine and react as expected (dark blue in focus, whitish when out of focus (= inactive)).

DwmEnableBlurBehindWindow with ToolWindowDwmEnableBlurBehindWindow with ToolWindow out of focus

A borderless window with resolved permission has the same behavior:

DwmEnableBlurBehindWindow with borderless but resizable window

A window without resizing without borders , however, will always look as if it is out of focus (as you can see in the last figure 3) when it is active and inactive. He always looks whitish:

DwmEnableBlurBehindWindow with borderless and non-resizable window

Here is a sample code of how I set the glass style:

 public MainWindow() { InitializeComponent(); WindowStyle = WindowStyle.None; ResizeMode = ResizeMode.NoResize; Height = 200; Background = Brushes.Transparent; Loaded += MainWindow_Loaded; } void MainWindow_Loaded(object sender, RoutedEventArgs e) { var windowInteropHelper = new WindowInteropHelper(this); var handle = windowInteropHelper.Handle; var mainWindowSrc = HwndSource.FromHwnd(handle); if (mainWindowSrc != null) if (mainWindowSrc.CompositionTarget != null) mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0); var glassParams = new DwmApi.DwmBlurbehind { dwFlags = DwmApi.DwmBlurbehind.DWM_BB_ENABLE, fEnable = true, hRegionBlur = IntPtr.Zero }; IntPtr dis = new IntPtr(2); DwmApi.DwmSetWindowAttribute(mainWindowSrc.Handle, DwmApi.DwmWindowAttribute.DWMWA_LAST, dis, sizeof(uint)); DwmApi.DwmEnableBlurBehindWindow( handle, glassParams ); } 

I tried to focus on the window, but this does not seem to affect the behavior. Any ideas or pointers on how to solve this?

+6
source share
1 answer

I didn’t work much in dwm apis, so I could be wrong, but I think that the dwm rendering policy by default uses WindowStyle to calculate the rendering. If you disable this policy, it will behave as you expected.

Add the following bit to fix your xD blues

 const int DWMWA_NCRENDERING_POLICY = 2; int DWMNCRP_DISABLED = 2; DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, ref DWMNCRP_DISABLED, sizeof(int)); 

For more on this voodoo, please check the following resources:

DwmSetWindowAttribute Function

DWMWINDOWATTRIBUTE enumeration

MainWindow.xaml

 <Window x:Class="dwm.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"/> 

MainWindow.xaml.cs

 using System; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; using System.Windows.Media; namespace dwm { public partial class MainWindow { [DllImport("dwmapi.dll", PreserveSig = false)] public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DwmBlurbehind blurBehind); [DllImport("dwmapi.dll", PreserveSig = true)] private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize); public MainWindow() { InitializeComponent(); } protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); var bb = new DwmBlurbehind { dwFlags = CoreNativeMethods.DwmBlurBehindDwFlags.DwmBbEnable, Enabled = true }; WindowStartupLocation = WindowStartupLocation.CenterScreen; Background = Brushes.Transparent; ResizeMode = ResizeMode.NoResize; WindowStyle = WindowStyle.None; Focus(); var hwnd = new WindowInteropHelper(this).Handle; HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent; DwmEnableBlurBehindWindow(hwnd, ref bb); const int dwmwaNcrenderingPolicy = 2; var dwmncrpDisabled = 2; DwmSetWindowAttribute(hwnd, dwmwaNcrenderingPolicy, ref dwmncrpDisabled, sizeof(int)); } [StructLayout(LayoutKind.Sequential)] public struct DwmBlurbehind { public CoreNativeMethods.DwmBlurBehindDwFlags dwFlags; public bool Enabled; public IntPtr BlurRegion; public bool TransitionOnMaximized; } public static class CoreNativeMethods { public enum DwmBlurBehindDwFlags { DwmBbEnable = 1, DwmBbBlurRegion = 2, DwmBbTransitionOnMaximized = 4 } } } } 

Focused Screenshot

Screenshothot with focus

Screen shot without focus

Screenoshot without focus

test environment

OS: Windows 8 - x64

Theme: Standard Windows

+8
source

Source: https://habr.com/ru/post/947883/


All Articles