Blur effect for WinForm - Issue with solution

409 Views Asked by At

I know this question have been answered with several ways but I am making this separate question in order to avoid potential queue of comments under initial question and its answers with which I am facing an "issue"(?).


What I am trying to achieve (in my case) is to apply what is called the Windows Blur Effect to a borderless WinForm.

I found this answer by György Kőszeg to a similar question and I adapted his code to my project like this:

First I made this BlurEffect class:

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

    internal enum WindowCompositionAttribute
    {
        WCA_ACCENT_POLICY = 19
    }

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

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

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

    internal static void Apply(Form form, bool enable)
    {
        var accent = new AccentPolicy { AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND };
        if (!enable)
            accent = new AccentPolicy { AccentState = AccentState.ACCENT_DISABLED };
        var accentStructSize = Marshal.SizeOf(accent);
        var accentPtr = Marshal.AllocHGlobal(accentStructSize);

        Marshal.StructureToPtr(accent, accentPtr, false);

        var data = new WindowCompositionAttributeData
        {
            Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
            SizeOfData = accentStructSize,
            Data = accentPtr
        };

        User32.SetWindowCompositionAttribute(form.Handle, ref data);
        Marshal.FreeHGlobal(accentPtr);
    }
}

And then, into my test Form, I added a property and a button so to enable or disable the Blur Effect:

public partial class MyForm : Form
{
    private bool blur_effect = false;
    [Category("• MyForm")]
    [DisplayName("• BlurEffect")]
    [Description("Enables or disables the [Blur] effect.")]
    public bool BlurEffect
    {
        get => this.blur_effect;
        set
        {
            this.blur_effect = value;
            BlurEffect.Apply(this, value);
            base.Invalidate();
        }
    }

    public MyForm()
    {
        InitializeComponent();
    }

    private void BlurEffect_Button_Click(object sender, EventArgs e)
    {
        this.BlurEffect = !this.BlurEffect;
    }
}

As you can see on the image below, it "worked" but I had this "issue"(?). Along with the form, the Βlur Effect is applied to the controls as well. Is that normal? Is there something I can do so the Blur Effect applies on the form only?

Note: Form's shadow comes from another class!!!

enter image description here

0

There are 0 best solutions below