How to Create acrylic transparency effect in C#

By FoxLearn 7/18/2024 7:47:37 AM   10.61K
Creating an acrylic transparency effect in a C# Windows Forms application can add a modern and sleek look to your user interface.

Acrylic transparency is a visual effect that blurs and partially transparent background elements, allowing the content behind them to show through subtly.

Acrylic Blur is a blur effect, you will often see this effect in the login screen of Windows 10 login. Here's a step-by-step guide on how to achieve this effect:

How to make form have blur effect in windows 10

Open Visual Studio and create 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
    }
}

Declare the necessary native methods to enable acrylic transparency. You need to import some functions from the Windows API using Platform Invocation Services (P/Invoke)

c# acrylic transparency effect

Add a method to enable the acrylic effect on your form. This method will use the previously declared native methods.

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);
}

With these steps,you can make windows 10 transparency effect in winform. Adjust the GradientColor field in the EnableAcrylic method to change the color of the acrylic effect. Remember, this effect is available only on Windows 10 and later versions.

Related