Windows Forms: How to Create acrylic transparency effect in C#

This post shows you How to Create acrylic transparency effect in C# Windows Forms Application.

Acrylic Blur is a blur effect, you will often see this effect in the login screen of Windows 10 login.

How to make form have blur effect in windows 10

Creating a new Windows Forms Application project, then create a EffectBlur class as shown below.

class EffectBlur
{
    internal enum AccentState
    {
        ACCENT_DISABLED = 0,
        ACCENT_ENABLE_GRADIENT = 1,
        ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
        ACCENT_ENABLE_BLURBEHIND = 3,
        ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
        ACCENT_INVALID_STATE = 5
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct AccentPolicy
    {
        public AccentState AccentState;
        public uint AccentFlags;
        public uint GradientColor;
        public uint AnimationId;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct WindowCompositionAttributeData
    {
        public WindowCompositionAttribute Attribute;
        public IntPtr Data;
        public int SizeOfData;
    }

    internal enum WindowCompositionAttribute
    {
        WCA_ACCENT_POLICY = 19
    }
}

c# acrylic transparency effect

Opening your form designer, then modify your form as shown below.

[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

private uint _blurOpacity;
public double BlurOpacity
{
    get { return _blurOpacity; }
    set { _blurOpacity = (uint)value; EnableBlur(); }
}

private uint _blurBackgroundColor = 0x990000;

internal void EnableBlur()
{
    var accent = new AccentPolicy();
    accent.AccentState = AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND;
    accent.GradientColor = (_blurOpacity << 24) | (_blurBackgroundColor & 0xFFFFFF);
    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);
}

Adding a Form_Load event handler allows you to enable acrylic blur effect.

private void Form1_Load(object sender, EventArgs e)
{
    this.BackColor = System.Drawing.ColorTranslator.FromHtml("#010000");
    EnableBlur();
}

You can also create an AppUtils class allows you to enable acrylic effect in Windows Forms Application.

public class AppUtils
{
    public static void EnableAcrylic(IWin32Window window, Color blurColor)
    {
        if (window is null)
            throw new ArgumentNullException(nameof(window));

        var accentPolicy = new AccentPolicy
        {
            AccentState = ACCENT.ENABLE_ACRYLICBLURBEHIND,
            GradientColor = ToAbgr(blurColor)
        };
        unsafe
        {
            SetWindowCompositionAttribute(new HandleRef(window, window.Handle), new WindowCompositionAttributeData
            {
                Attribute = WCA.ACCENT_POLICY,
                Data = &accentPolicy,
                DataLength = Marshal.SizeOf<AccentPolicy>()
            });
        }
    }

    private static uint ToAbgr(Color color)
    {
        return ((uint)color.A << 24)
            | ((uint)color.B << 16)
            | ((uint)color.G << 8)
            | color.R;
    }

    [DllImport("user32.dll")]
    private static extern int SetWindowCompositionAttribute(HandleRef hWnd, in WindowCompositionAttributeData data);

    private unsafe struct WindowCompositionAttributeData
    {
        public WCA Attribute;
        public void* Data;
        public int DataLength;
    }

    private enum WCA
    {
        ACCENT_POLICY = 19
    }

    private enum ACCENT
    {
        DISABLED = 0,
        ENABLE_GRADIENT = 1,
        ENABLE_TRANSPARENTGRADIENT = 2,
        ENABLE_BLURBEHIND = 3,
        ENABLE_ACRYLICBLURBEHIND = 4,
        INVALID_STATE = 5
    }

    private struct AccentPolicy
    {
        public ACCENT AccentState;
        public uint AccentFlags;
        public uint GradientColor;
        public uint AnimationId;
    }
}

And don't forget to check "Allow unsafe code" by right-clicking on your project, then select Properties => Build.

Finaly, You need to override OnHandleCreated and OnPaintBackground as shown below.

protected override void OnHandleCreated(EventArgs e)
{
    AppUtils.EnableAcrylic(this, Color.Transparent);
    base.OnHandleCreated(e);
}

protected override void OnPaintBackground(PaintEventArgs e)
{
    e.Graphics.Clear(Color.Transparent);
}

Through this c# example, i hope so you can make windows 10 transparency effect in winform.

Related