简体   繁体   English

如何在 Windows 窗体中创建半透明或模糊的背景色

[英]How to create a semi transparent or blurred backcolor in a Windows Form

I am creating a Speed Meter to measure my internet speed and stays at top of every app, then I how do I make Its background semi transparent or blurred something like this.我正在创建一个速度计来测量我的互联网速度并保持在每个应用程序的顶部,然后我如何使它的背景半透明或像这样模糊。

在此处输入图片说明

A WinForms Form with a Blur effect applied to it, using:应用了模糊效果的WinForms Form ,使用:
Windows 7 ⇒ DwmEnableBlurBehindWindow() DWM function. Windows 7 ⇒ DwmEnableBlurBehindWindow() DWM 函数。
Windows 10 ⇒ SetWindowCompositionAttribute() User32 function (undocumented) Windows 10 ⇒ SetWindowCompositionAttribute() User32函数(未记录)

How to apply the Blur Behind effect :如何应用模糊背后效果
Windows 7 :视窗 7
The Window needs to register a rendering policy with DwmSetWindowAttribute() , setting the DWMWINDOWATTRIBUTE enumerator to NCRenderingPolicy and enable it, setting the DWMNCRENDERINGPOLICY enumerator to Enabled . Window 需要使用DwmSetWindowAttribute()注册渲染策略,将DWMWINDOWATTRIBUTE枚举器设置为NCRenderingPolicy并启用它,将DWMNCRENDERINGPOLICY枚举器设置为Enabled
You may also want to override a Form's class WndProc ;您可能还想覆盖 Form 的类WndProc when a WM_DWMCOMPOSITIONCHANGED message is received (informing of the Aero composition state), to verify whether DWN Composition is enabled.当收到WM_DWMCOMPOSITIONCHANGED消息(通知 Aero 组合状态)时,验证是否启用了 DWN 组合。

Before showing the Window interface, call DwmEnableBlurBehindWindow() , setting its DWM_BLURBEHIND structure relevant fields ( dwFlags and fEnable ) to 1 .在显示 Window 界面之前,调用DwmEnableBlurBehindWindow() ,将其DWM_BLURBEHIND结构相关字段( dwFlagsfEnable )设置为1
Here, I'm calling it from the Form's constructor.在这里,我从 Form 的构造函数中调用它。

Windows 10 :视窗 10
This code is using the not yet documented SetWindowCompositionAttribute() function.此代码使用尚未记录的SetWindowCompositionAttribute()函数。
The User32 function only requires the use of an internal structure, here called WinCompositionAttrData , where the Attribute member is set to DWMWINDOWATTRIBUTE.AccentPolicy and the Data member is set to the pointer of an internal structure, here called AccentPolicy , where the AccentState member is set to DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND User32函数只需要使用内部结构,此处称为WinCompositionAttrData ,其中Attribute成员设置为DWMWINDOWATTRIBUTE.AccentPolicyData成员设置为内部结构的指针,此处称为AccentPolicy ,其中设置了AccentState成员到DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND

DWM Compostion is always enabled. DWM 组合始终处于启用状态。 No need to verify it or override WndProc to handle a DWM Composition change.无需验证或覆盖WndProc即可处理 DWM 组合更改。

It's more clear in code:在代码中更清楚:
(As a note, the BlurBehind effect does not work if the Form has a white background color) (请注意,如果窗体具有白色背景色,则BlurBehind效果不起作用)

See this other question about a DwmExtendFrameIntoClientArea() implementation. 请参阅有关DwmExtendFrameIntoClientArea()实现的其他问题

public partial class frmBlurBehind : Form
{
    WinApi.Dwm.DWMNCRENDERINGPOLICY policy = WinApi.Dwm.DWMNCRENDERINGPOLICY.Enabled;
    WinApi.Dwm.WindowSetAttribute(this.Handle, WinApi.Dwm.DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
    Version osVersion = Environment.OSVersion.Version;
    if (DWNCompositionEnabled()) {
        if (osVersion.Major > 6)
        {
            WinApi.Dwm.Windows10EnableBlurBehind(this.Handle);
        }
        else if(osVersion.Major == 6 && osVersion.Minor == 1)
        {
            WinApi.Dwm.WindowEnableBlurBehind(this.Handle);
        }
    }

    private bool IsDWNCompositionEnabled() => (Environment.OSVersion.Version.Major >= 6)
                                           ? WinApi.Dwm.IsCompositionEnabled()
                                           : false;

    //Eventually
    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case (int)WinApi.WinMessage.WM_DWMCOMPOSITIONCHANGED:
                if (IsDWNCompositionEnabled())
                {
                    WinApi.Dwm.DWMNCRENDERINGPOLICY policy = WinApi.Dwm.DWMNCRENDERINGPOLICY.Enabled;
                    WinApi.Dwm.WindowSetAttribute(this.Handle, WinApi.Dwm.DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
                    WinApi.Dwm.WindowBorderlessDropShadow(this.Handle, 1);
                    m.Result = (IntPtr)0;
                }
                break;
            default:
                break;
        }
        base.WndProc(ref m);
    }
}


public partial class WinApi
{
    public enum WinMessage : int
    {
        WM_DWMCOMPOSITIONCHANGED = 0x031E,          //The system will send a window the WM_DWMCOMPOSITIONCHANGED message to indicate that the availability of desktop composition has changed.
        WM_DWMNCRENDERINGCHANGED = 0x031F,          //WM_DWMNCRENDERINGCHANGED is called when the non-client area rendering status of a window has changed. Only windows that have set the flag DWM_BLURBEHIND.fTransitionOnMaximized to true will get this message.
        WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320,    //Sent to all top-level windows when the colorization color has changed.
        WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321        //WM_DWMWINDOWMAXIMIZEDCHANGE will let you know when a DWM composed window is maximized. You also have to register for this message as well. You'd have other windowd go opaque when this message is sent.
    }

    public class Dwm

        public enum DWMWINDOWATTRIBUTE : uint
        {
            NCRenderingEnabled = 1,     //Get only atttribute
            NCRenderingPolicy,          //Enable or disable non-client rendering
            TransitionsForceDisabled,
            AllowNCPaint,
            CaptionButtonBounds,
            NonClientRtlLayout,
            ForceIconicRepresentation,
            Flip3DPolicy,
            ExtendedFrameBounds,
            HasIconicBitmap,
            DisallowPeek,
            ExcludedFromPeek,
            Cloak,
            Cloaked,
            FreezeRepresentation
            PlaceHolder1,
            PlaceHolder2,
            PlaceHolder3,
            AccentPolicy = 19
        }

        public enum DWMNCRENDERINGPOLICY : uint
        {
            UseWindowStyle, // Enable/disable non-client rendering based on window style
            Disabled,       // Disabled non-client rendering; window style is ignored
            Enabled,        // Enabled non-client rendering; window style is ignored
        };

        // Values designating how Flip3D treats a given window.
        enum DWMFLIP3DWINDOWPOLICY : uint
        {
            Default,        // Hide or include the window in Flip3D based on window style and visibility.
            ExcludeBelow,   // Display the window under Flip3D and disabled.
            ExcludeAbove,   // Display the window above Flip3D and enabled.
        };

        [StructLayout(LayoutKind.Sequential)]
        public struct DWM_BLURBEHIND
        {
            public DWM_BB dwFlags;
            public int fEnable;
            public IntPtr hRgnBlur;
            public int fTransitionOnMaximized;

            public DWM_BLURBEHIND(bool enabled)
            {
                dwFlags = DWM_BB.Enable;
                fEnable = (enabled) ? 1 : 0;
                hRgnBlur = IntPtr.Zero;
                fTransitionOnMaximized = 0;
            }

        [Flags]
        public enum DWM_BB
        {
            Enable = 1,
            BlurRegion = 2,
            TransitionOnMaximized = 4
        }

        public enum DWMACCENTSTATE
        {
            ACCENT_DISABLED = 0,
            ACCENT_ENABLE_GRADIENT = 1,
            ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
            ACCENT_ENABLE_BLURBEHIND = 3,
            ACCENT_INVALID_STATE = 4
        }

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

            public AccentPolicy(DWMACCENTSTATE accentState, int accentFlags, int gradientColor, int animationId)
            {
                AccentState = accentState;
                AccentFlags = accentFlags;
                GradientColor = gradientColor;
                AnimationId = animationId;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WinCompositionAttrData
        {
            public DWMWINDOWATTRIBUTE Attribute;
            public IntPtr Data;  //Will point to an AccentPolicy struct, where Attribute will be DWMWINDOWATTRIBUTE.AccentPolicy
            public int SizeOfData;

            public WinCompositionAttrData(DWMWINDOWATTRIBUTE attribute, IntPtr data, int sizeOfData)
            {
                Attribute = attribute;
                Data = data;
                SizeOfData = sizeOfData;
            }
        }

        public struct MARGINS
        {
            public int leftWidth;
            public int rightWidth;
            public int topHeight;
            public int bottomHeight;

            public MARGINS(int LeftWidth, int RightWidth, int TopHeight, int BottomHeight)
            {
                leftWidth = LeftWidth;
                rightWidth = RightWidth;
                topHeight = TopHeight;
                bottomHeight = BottomHeight;
            }

            public void NoMargins()
            {
                leftWidth = 0;
                rightWidth = 0;
                topHeight = 0;
                bottomHeight = 0;
            }

            public void SheetOfGlass()
            {
                leftWidth = -1;
                rightWidth = -1;
                topHeight = -1;
                bottomHeight = -1;
            }
        }


        [SuppressUnmanagedCodeSecurity]
        internal static class SafeNativeMethods
        {
            //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969508(v=vs.85).aspx
            [DllImport("dwmapi.dll")]
            internal static extern int DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);

            //https://msdn.microsoft.com/it-it/library/windows/desktop/aa969512(v=vs.85).aspx
            [DllImport("dwmapi.dll")]
            internal static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);

            //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969515(v=vs.85).aspx
            [DllImport("dwmapi.dll")]
            internal static extern int DwmGetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);

            //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969524(v=vs.85).aspx
            [DllImport("dwmapi.dll")]
            internal static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);

            [DllImport("User32.dll", SetLastError = true)]
            internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WinCompositionAttrData data);

            [DllImport("dwmapi.dll")]
            internal static extern int DwmIsCompositionEnabled(ref int pfEnabled);
        }

        public static bool IsCompositionEnabled()
        {
            int pfEnabled = 0;
            int result = SafeNativeMethods.DwmIsCompositionEnabled(ref pfEnabled);
            return (pfEnabled == 1) ? true : false;
        }

        public static bool IsNonClientRenderingEnabled(IntPtr hWnd)
        {
            int gwaEnabled = 0;
            int result = SafeNativeMethods.DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingEnabled, ref gwaEnabled, sizeof(int));
            return (gwaEnabled == 1) ? true : false;
        }

        public static bool WindowSetAttribute(IntPtr hWnd, DWMWINDOWATTRIBUTE Attribute, int AttributeValue)
        {
            int result = SafeNativeMethods.DwmSetWindowAttribute(hWnd, Attribute, ref AttributeValue, sizeof(int));
            return (result == 0);
        }

        public static void Windows10EnableBlurBehind(IntPtr hWnd)
        {
            AccentPolicy accPolicy = new AccentPolicy() {
                AccentState = DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND,
            };

            int accentSize = Marshal.SizeOf(accPolicy);
            IntPtr accentPtr = Marshal.AllocHGlobal(accentSize);
            Marshal.StructureToPtr(accPolicy, accentPtr, false);
            var data = new WinCompositionAttrData(DWMWINDOWATTRIBUTE.AccentPolicy, accentPtr, accentSize);

            SafeNativeMethods.SetWindowCompositionAttribute(hWnd, ref data);
            Marshal.FreeHGlobal(accentPtr);
        }

        public static bool WindowEnableBlurBehind(IntPtr hWnd)
        {
            //Create and populate the Blur Behind structure
            DWM_BLURBEHIND Dwm_BB = new DWM_BLURBEHIND(true);

            int result = SafeNativeMethods.DwmEnableBlurBehindWindow(hWnd, ref Dwm_BB);
            return (result == 0);
        }

        public static bool WindowExtendIntoClientArea(IntPtr hWnd, WinApi.Dwm.MARGINS Margins)
        {
            // Extend frame on the bottom of client area
            int result = SafeNativeMethods.DwmExtendFrameIntoClientArea(hWnd, ref Margins);
            return (result == 0);
        }

        public static bool WindowBorderlessDropShadow(IntPtr hWnd, int ShadowSize)
        {
            MARGINS Margins = new MARGINS(0, ShadowSize, 0, ShadowSize);
            int result = SafeNativeMethods.DwmExtendFrameIntoClientArea(hWnd, ref Margins);
            return (result == 0);
        }

        public static bool WindowSheetOfGlass(IntPtr hWnd)
        {
            MARGINS Margins = new MARGINS();
            Margins.SheetOfGlass();

            //Margins set to All:-1 - Sheet Of Glass effect
            int result = SafeNativeMethods.DwmExtendFrameIntoClientArea(hWnd, ref Margins);
            return (result == 0);
        }

        public static bool WindowDisableRendering(IntPtr hWnd)
        {
            DWMNCRENDERINGPOLICY NCRP = DWMNCRENDERINGPOLICY.Disabled;
            int ncrp = (int)NCRP;
            // Disable non-client area rendering on the window.
            int result = SafeNativeMethods.DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, ref ncrp, sizeof(int));
            return (result == 0);
        }
    }
}

This is a sample result with a Form.BackColor set to MidnightBlue :这是一个将Form.BackColor设置为MidnightBlue的示例结果:

在此处输入图片说明

                Window Selected                              Windows Unselected

With some controls on it:对其进行一些控制:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM