Browse Source

[Win32] Use WS_EX_LAYERED style for native control holders with winui composition

pull/7111/head
Nikita Tsukanov 4 years ago
parent
commit
5d91fa5df9
  1. 10
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  2. 17
      src/Windows/Avalonia.Win32/Win32NativeControlHost.cs
  3. 2
      src/Windows/Avalonia.Win32/WindowImpl.cs

10
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -1467,6 +1467,16 @@ namespace Avalonia.Win32.Interop
[DllImport("dwmapi.dll")] [DllImport("dwmapi.dll")]
public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind); public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);
[Flags]
public enum LayeredWindowFlags
{
LWA_ALPHA = 0x00000002,
LWA_COLORKEY = 0x00000001,
}
[DllImport("user32.dll")]
public static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, LayeredWindowFlags dwFlags);
[Flags] [Flags]
public enum DWM_BB public enum DWM_BB

17
src/Windows/Avalonia.Win32/Win32NativeControlHost.cs

@ -9,10 +9,12 @@ namespace Avalonia.Win32
{ {
class Win32NativeControlHost : INativeControlHostImpl class Win32NativeControlHost : INativeControlHostImpl
{ {
private readonly bool _useLayeredWindow;
public WindowImpl Window { get; } public WindowImpl Window { get; }
public Win32NativeControlHost(WindowImpl window) public Win32NativeControlHost(WindowImpl window, bool useLayeredWindow)
{ {
_useLayeredWindow = useLayeredWindow;
Window = window; Window = window;
} }
@ -25,12 +27,12 @@ namespace Avalonia.Win32
public INativeControlHostDestroyableControlHandle CreateDefaultChild(IPlatformHandle parent) public INativeControlHostDestroyableControlHandle CreateDefaultChild(IPlatformHandle parent)
{ {
AssertCompatible(parent); AssertCompatible(parent);
return new DumbWindow(parent.Handle); return new DumbWindow(false, parent.Handle);
} }
public INativeControlHostControlTopLevelAttachment CreateNewAttachment(Func<IPlatformHandle, IPlatformHandle> create) public INativeControlHostControlTopLevelAttachment CreateNewAttachment(Func<IPlatformHandle, IPlatformHandle> create)
{ {
var holder = new DumbWindow(Window.Handle.Handle); var holder = new DumbWindow(_useLayeredWindow, Window.Handle.Handle);
Win32NativeControlAttachment attachment = null; Win32NativeControlAttachment attachment = null;
try try
{ {
@ -52,7 +54,7 @@ namespace Avalonia.Win32
public INativeControlHostControlTopLevelAttachment CreateNewAttachment(IPlatformHandle handle) public INativeControlHostControlTopLevelAttachment CreateNewAttachment(IPlatformHandle handle)
{ {
AssertCompatible(handle); AssertCompatible(handle);
return new Win32NativeControlAttachment(new DumbWindow(Window.Handle.Handle), return new Win32NativeControlAttachment(new DumbWindow(_useLayeredWindow, Window.Handle.Handle),
handle) { AttachedTo = this }; handle) { AttachedTo = this };
} }
@ -67,7 +69,7 @@ namespace Avalonia.Win32
UnmanagedMethods.WndProc _wndProcDelegate; UnmanagedMethods.WndProc _wndProcDelegate;
private readonly string _className; private readonly string _className;
public DumbWindow(IntPtr? parent = null) public DumbWindow(bool layered = false, IntPtr? parent = null)
{ {
_wndProcDelegate = WndProc; _wndProcDelegate = WndProc;
var wndClassEx = new UnmanagedMethods.WNDCLASSEX var wndClassEx = new UnmanagedMethods.WNDCLASSEX
@ -80,7 +82,7 @@ namespace Avalonia.Win32
var atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx); var atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx);
Handle = UnmanagedMethods.CreateWindowEx( Handle = UnmanagedMethods.CreateWindowEx(
0, layered ? (int)UnmanagedMethods.WindowStyles.WS_EX_LAYERED : 0,
atom, atom,
null, null,
(int)UnmanagedMethods.WindowStyles.WS_CHILD, (int)UnmanagedMethods.WindowStyles.WS_CHILD,
@ -92,6 +94,9 @@ namespace Avalonia.Win32
IntPtr.Zero, IntPtr.Zero,
IntPtr.Zero, IntPtr.Zero,
IntPtr.Zero); IntPtr.Zero);
if (layered)
UnmanagedMethods.SetLayeredWindowAttributes(Handle, 0, 255,
UnmanagedMethods.LayeredWindowFlags.LWA_ALPHA);
} }

2
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -145,7 +145,7 @@ namespace Avalonia.Win32
Screen = new ScreenImpl(); Screen = new ScreenImpl();
_nativeControlHost = new Win32NativeControlHost(this); _nativeControlHost = new Win32NativeControlHost(this, _isUsingComposition);
s_instances.Add(this); s_instances.Add(this);
} }

Loading…
Cancel
Save