Browse Source

add basic win32 implementation for transparency level.

pull/3962/head
Dan Walmsley 6 years ago
parent
commit
fe7e8582d1
  1. 41
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  2. 68
      src/Windows/Avalonia.Win32/WindowImpl.cs

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

@ -1302,6 +1302,47 @@ namespace Avalonia.Win32.Interop
[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);
[DllImport("dwmapi.dll")]
public static extern int DwmIsCompositionEnabled(out bool enabled);
[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
[StructLayout(LayoutKind.Sequential)]
internal struct WindowCompositionAttributeData
{
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}
internal enum WindowCompositionAttribute
{
// ...
WCA_ACCENT_POLICY = 19
// ...
}
internal enum AccentState
{
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_ENABLE_ACRYLIC = 4, //1703 and above
ACCENT_ENABLE_HOSTBACKDROP = 5, // RS5 1809
ACCENT_INVALID_STATE = 6
}
[StructLayout(LayoutKind.Sequential)]
internal struct AccentPolicy
{
public AccentState AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MARGINS
{

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

@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Media;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
@ -66,6 +67,7 @@ namespace Avalonia.Win32
private Size _minSize;
private Size _maxSize;
private WindowImpl _parent;
private WindowTransparencyLevel _transparencyLevel = WindowTransparencyLevel.None;
public WindowImpl()
{
@ -122,6 +124,8 @@ namespace Avalonia.Win32
public Action<WindowState> WindowStateChanged { get; set; }
public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; }
public Thickness BorderThickness
{
get
@ -206,6 +210,70 @@ namespace Avalonia.Win32
}
}
public WindowTransparencyLevel TransparencyLevel
{
get => _transparencyLevel;
set
{
var oldValue = _transparencyLevel;
_transparencyLevel = EnableBlur(value);
if(oldValue != _transparencyLevel)
{
TransparencyLevelChanged?.Invoke(_transparencyLevel);
}
}
}
private WindowTransparencyLevel EnableBlur(WindowTransparencyLevel transparencyLevel)
{
if(DwmIsCompositionEnabled(out var compositionEnabled) != 0 || !compositionEnabled)
{
return WindowTransparencyLevel.None;
}
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf(accent);
switch (transparencyLevel)
{
default:
case WindowTransparencyLevel.None:
accent.AccentState = AccentState.ACCENT_DISABLED;
break;
case WindowTransparencyLevel.Transparent:
accent.AccentState = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT;
break;
case WindowTransparencyLevel.Blur:
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
break;
case (WindowTransparencyLevel.Blur + 1):
accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLIC;
break;
}
var bgcolor = 0x00ffffff;
accent.GradientColor = bgcolor;
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData();
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = accentStructSize;
data.Data = accentPtr;
SetWindowCompositionAttribute(_hwnd, ref data);
Marshal.FreeHGlobal(accentPtr);
//todo return acheived level and check windows versions.
return transparencyLevel;
}
public IEnumerable<object> Surfaces => new object[] { Handle, _gl, _framebuffer };
public PixelPoint Position

Loading…
Cancel
Save