I am using the undocumented SetWindowCompositionAtribute API in user32.dll to make my windows form have a blur effect. This is the code I am using:
public Form1()
{
InitializeComponent();
this.EnableBlur();
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
BackColor = Color.LimeGreen;
TransparencyKey = Color.LimeGreen;
}
//import dlls
[DllImport("uxtheme.dll", EntryPoint = "#95")]
public static extern uint GetImmersiveColorFromColorSetEx(uint dwImmersiveColorSet, uint dwImmersiveColorType, bool bIgnoreHighContrast, uint dwHighContrastCacheMode);
[DllImport("uxtheme.dll", EntryPoint = "#96")]
public static extern uint GetImmersiveColorTypeFromName(IntPtr pName);
[DllImport("uxtheme.dll", EntryPoint = "#98")]
public static extern int GetImmersiveUserColorSetPreference(bool bForceCheckRegistry, bool bSkipCheckOnFail);
// Get theme color
public Color GetThemeColor()
{
var colorSetEx = GetImmersiveColorFromColorSetEx(
(uint)GetImmersiveUserColorSetPreference(false, false),
GetImmersiveColorTypeFromName(Marshal.StringToHGlobalUni("ImmersiveStartSelectionBackground")),
false, 0);
var colour = Color.FromArgb((byte)((0xFF000000 & colorSetEx) >> 24), (byte)(0x000000FF & colorSetEx),
(byte)((0x0000FF00 & colorSetEx) >> 8), (byte)((0x00FF0000 & colorSetEx) >> 16));
return colour;
}
//Class to use user32.dll API
public static class WindowExtension
{
[DllImport("user32.dll")]
static internal extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
public static void EnableBlur(this Form @this)
{
var accent = new AccentPolicy();
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
var accentStructSize = Marshal.SizeOf(accent);
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(@this.Handle, ref Data);
Marshal.FreeHGlobal(accentPtr);
}
}
enum AccentState
{
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4,
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
}
struct AccentPolicy
{
public AccentState AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
}
struct WindowCompositionAttributeData
{
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}
enum WindowCompositionAttribute
{
WCA_ACCENT_POLICY = 19,
}
Here is the effect:
I have tried changing AccentPolicy.GradientColor to 1, 2, 3, 4, 5 but the blur is still colorless.
I want the blur on the Form to be the same as the accent color using my GetThemeColor()
method
How do I do this?
User contributions licensed under CC BY-SA 3.0