Enable Vista Glass Effect in WPF Borderless Window

I wrote an attached property that I can set in the window to expand the glass border to the client area (using the DwmExtendFrameIntoClientArea API). In most cases, it works great. Now I want my window to be borderless, so I set the following attributes in my window:

  WindowStyle="None" ResizeMode="NoResize" Background="Transparent" u:WinUtil.EnableGlass="True" ShowInTaskbar="False" 

But with these attributes the glass does not appear at all: there is a transparent background in my window. If I set ResizeMode to CanResize , the glass will be shown, but I do not want the window to resize.

I suspect that this is due to the fact that the glass effect is obtained by expanding the frame without a client in the client area: with WindowStyle = None and ResizeMode = NoResize there is no frame without a client, so there is nothing to expand. When I enable resizing, it creates a frame around the window, so the frame can be expanded.

I suppose it should be possible to create a window with a thin border, without a title, and cannot be changed by setting the corresponding WS_ * bits, but I don’t know which ones

So my questions are:

  • What style bits should be set or unset to have the desired look and feel?
  • How can I initialize window style bits? The Window class does not seem to be similar to the Windows Forms CreateParams property ... Do I need to set these bits after creating the handle?
  • I found the HwndSource class, which might be the answer to question 2, but it seems a bit complicated to use if you are not a Win32 expert ... Would that be a smart solution to my problem?

Any advice is welcome

+3
windows wpf aero-glass
source share
2 answers

Have you tried using DwmEnableBlurBehindWindow ? This allows you to make a certain part of the transparent area of ​​the window.

+5
source share

I had a window in which I wanted to give only a glass panel (without a title and without resizing) and ran into the same problem as you. You cannot do this by setting the Window style. My solution was to set ResizeMode = "CanResize" and WindowStyle = "None" and then handle the WM_NCHITTEST event in order to convert the modified remote boundary hits to immutable boundary images. It was also necessary to change the window style to disable maximization and minimization (using Windows shortcuts) and the system menu:

 private void Window_SourceInitialized(object sender, EventArgs e) { System.Windows.Interop.HwndSource source = (System.Windows.Interop.HwndSource)PresentationSource.FromVisual(this); source.AddHook(new System.Windows.Interop.HwndSourceHook(HwndSourceHook)); IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; IntPtr flags = GetWindowLongPtr(hWnd, -16 /*GWL_STYLE*/); SetWindowLongPtr(hWnd, -16 /*GWL_STYLE*/, new IntPtr(flags.ToInt64() & ~(0x00010000L /*WS_MAXIMIZEBOX*/ | 0x00020000L /*WS_MINIMIZEBOX*/ | 0x00080000L /*WS_SYSMENU*/))); } private static IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case 0x0084 /*WM_NCHITTEST*/: IntPtr result = DefWindowProc(hwnd, msg, wParam, lParam); if (result.ToInt32() >= 10 /*HTLEFT*/ && result.ToInt32() <= 17 /*HTBOTTOMRIGHT*/ ) { handled = true; return new IntPtr(18 /*HTBORDER*/); } break; } return IntPtr.Zero; } [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); 

This gives you a window in Windows 7 suitable for pop-ups in the notification area (like clock or volume pop-ups). BTW, you can reproduce the shading at the bottom of the popup by creating a 44-height control and setting its background:

 <Control.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="{x:Static SystemColors.GradientActiveCaptionColor}" Offset="0"/> <GradientStop Color="{x:Static SystemColors.InactiveBorderColor}" Offset="0.1"/> </LinearGradientBrush> </Control.Background> 
+4
source share

All Articles