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

Arw*_*hua 5 .net c# winapi dwm winforms

我正在创建一个速度计来测量我的互联网速度并保持在每个应用程序的顶部,然后我如何使其背景半透明或模糊类似这样。

在此输入图像描述

Jim*_*imi 8

WinForms Form应用了模糊效果的A ,使用:
\nWindows 7 \xe2\x87\x92 DwmEnableBlurBehindWindow() DWM 函数。
\nWindows 10 / 11 \xe2\x87\x92函数(未记录)SetWindowCompositionAttribute() User32

\n

如何应用模糊后面效果
\n Windows 7: \n窗口需要使用DwmSetWindowAttribute()
注册渲染策略,将 DWMWINDOWATTRIBUTE枚举器设置为并启用它,将DWMNCRENDERINGPOLICY枚举器设置为。\n您可能还想覆盖 Form 的类;当收到WM_DWMCOMPOSITIONCHANGED消息(通知 Aero 合成状态)时,验证是否启用了 DWM 合成。NCRenderingPolicyEnabled
WndProc

\n

在显示 Window 界面之前,调用DwmEnableBlurBehindWindow(),将其DWM_BLURBEHIND结构相关字段(dwFlagsfEnable)设置为1
\n在这里,我从 Form 的构造函数中调用它。

\n

Windows 10Windows 11
\n此代码使用尚未记录的SetWindowCompositionAttribute()函数。
\n该User32函数只需要使用一个内部结构,这里称为WinCompositionAttrData,其中Attribute成员设置为 DWMWINDOWATTRIBUTE.AccentPolicy,并且该Data成员设置为内部结构的指针,这里称为AccentPolicy,其中AccentState成员设置为DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND

\n

DWM 合成始终处于启用状态。无需验证或覆盖WndProc即可处理 DWM 组合更改。

\n

代码中更清楚:
\n(请注意,如果表单具有白色BlurBehind背景颜色,则效果不起作用)

\n

请参阅有关实施的其他问题DwmExtendFrameIntoClientArea()

\n
public partial class frmBlurBehind : Form\n{\n    public frmBlurBehind()\n    {\n        InitializeComponent();\n\n        // Remove the border if this is meant to be a border-less Form\n        // FormBorderStyle = FormBorderStyle.None;\n\n        if (IsDWMCompositionEnabled()) {\n            if (Environment.OSVersion.Version.Major > 6) {\n                Dwm.Windows10EnableBlurBehind(Handle);\n            }\n            else {\n                Dwm.WindowEnableBlurBehind(Handle);\n            }\n            // Set Drop shadow of a border-less Form\n            if (FormBorderStyle == FormBorderStyle.None) {\n                Dwm.WindowBorderlessDropShadow(Handle, 2);\n            }\n        }\n    }\n\n    private bool IsDWMCompositionEnabled() => \n        Environment.OSVersion.Version.Major >= 6 && Dwm.IsCompositionEnabled();\n\n    // Eventually, if this is a border-less Form, reapply the attribute if DWM Composition changes\n    protected override void WndProc(ref Message m)\n    {\n        base.WndProc(ref m);\n        switch (m.Msg) {\n            case Dwm.WM_DWMCOMPOSITIONCHANGED:\n                if (IsDWMCompositionEnabled()) {\n                    Dwm.DWMNCRENDERINGPOLICY policy = Dwm.DWMNCRENDERINGPOLICY.Enabled;\n                    Dwm.WindowSetAttribute(Handle, Dwm.DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);\n                    Dwm.WindowBorderlessDropShadow(Handle, 2);\n                    m.Result = IntPtr.Zero;\n                }\n                break;\n            default:\n                break;\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

该类Dwm包含上面使用的所有互操作函数和结构,以及许多在此上下文中可能有用的其他方法

\n
[SuppressUnmanagedCodeSecurity]\npublic class Dwm {\n    public const int WM_DWMCOMPOSITIONCHANGED = 0x031E;\n\n    public struct MARGINS {\n        public int leftWidth;\n        public int rightWidth;\n        public int topHeight;\n        public int bottomHeight;\n\n        public MARGINS(int LeftWidth, int RightWidth, int TopHeight, int BottomHeight)\n        {\n            leftWidth = LeftWidth;\n            rightWidth = RightWidth;\n            topHeight = TopHeight;\n            bottomHeight = BottomHeight;\n        }\n\n        public void NoMargins()\n        {\n            leftWidth = 0;\n            rightWidth = 0;\n            topHeight = 0;\n            bottomHeight = 0;\n        }\n\n        public void SheetOfGlass()\n        {\n            leftWidth = -1;\n            rightWidth = -1;\n            topHeight = -1;\n            bottomHeight = -1;\n        }\n    }\n\n    [Flags]\n    public enum DWM_BB {\n        Enable = 1,\n        BlurRegion = 2,\n        TransitionOnMaximized = 4\n    }\n\n    // https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute\n    public enum DWMWINDOWATTRIBUTE : uint {\n        NCRenderingEnabled = 1,       //Get atttribute\n        NCRenderingPolicy,            //Enable or disable non-client rendering\n        TransitionsForceDisabled,\n        AllowNCPaint,\n        CaptionButtonBounds,          //Get atttribute\n        NonClientRtlLayout,\n        ForceIconicRepresentation,\n        Flip3DPolicy,\n        ExtendedFrameBounds,          //Get atttribute\n        HasIconicBitmap,\n        DisallowPeek,\n        ExcludedFromPeek,\n        Cloak,\n        Cloaked,                      //Get atttribute. Returns a DWMCLOACKEDREASON\n        FreezeRepresentation,\n        PassiveUpdateMode,\n        UseHostBackDropBrush,\n        AccentPolicy = 19,            // Win 10 (undocumented)\n        ImmersiveDarkMode = 20,       // Win 11 22000\n        WindowCornerPreference = 33,  // Win 11 22000\n        BorderColor,                  // Win 11 22000\n        CaptionColor,                 // Win 11 22000\n        TextColor,                    // Win 11 22000\n        VisibleFrameBorderThickness,  // Win 11 22000\n        SystemBackdropType            // Win 11 22621\n    }\n\n    public enum DWMCLOACKEDREASON : uint {\n        DWM_CLOAKED_APP = 0x0000001,       //cloaked by its owner application.\n        DWM_CLOAKED_SHELL = 0x0000002,     //cloaked by the Shell.\n        DWM_CLOAKED_INHERITED = 0x0000004  //inherited from its owner window.\n    }\n\n    public enum DWMNCRENDERINGPOLICY : uint {\n        UseWindowStyle, // Enable/disable non-client rendering based on window style\n        Disabled,       // Disabled non-client rendering; window style is ignored\n        Enabled,        // Enabled non-client rendering; window style is ignored\n    };\n\n    public enum DWMACCENTSTATE {\n        ACCENT_DISABLED = 0,\n        ACCENT_ENABLE_GRADIENT = 1,\n        ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,\n        ACCENT_ENABLE_BLURBEHIND = 3,\n        ACCENT_INVALID_STATE = 4\n    }\n\n    [Flags]\n    public enum CompositionAction : uint {\n        DWM_EC_DISABLECOMPOSITION = 0,\n        DWM_EC_ENABLECOMPOSITION = 1\n    }\n\n    // Values designating how Flip3D treats a given window.\n    enum DWMFLIP3DWINDOWPOLICY : uint {\n        Default,        // Hide or include the window in Flip3D based on window style and visibility.\n        ExcludeBelow,   // Display the window under Flip3D and disabled.\n        ExcludeAbove,   // Display the window above Flip3D and enabled.\n    };\n\n    public enum ThumbProperties_dwFlags : uint {\n        RectDestination = 0x00000001,\n        RectSource = 0x00000002,\n        Opacity = 0x00000004,\n        Visible = 0x00000008,\n        SourceClientAreaOnly = 0x00000010\n    }\n\n\n    [StructLayout(LayoutKind.Sequential)]\n    public struct AccentPolicy {\n        public DWMACCENTSTATE AccentState;\n        public int AccentFlags;\n        public int GradientColor;\n        public int AnimationId;\n\n        public AccentPolicy(DWMACCENTSTATE accentState, int accentFlags, int gradientColor, int animationId)\n        {\n            AccentState = accentState;\n            AccentFlags = accentFlags;\n            GradientColor = gradientColor;\n            AnimationId = animationId;\n        }\n    }\n\n    [StructLayout(LayoutKind.Sequential)]\n    public struct DWM_BLURBEHIND {\n        public DWM_BB dwFlags;\n        public int fEnable;\n        public IntPtr hRgnBlur;\n        public int fTransitionOnMaximized;\n\n        public DWM_BLURBEHIND(bool enabled)\n        {\n            dwFlags = DWM_BB.Enable;\n            fEnable = (enabled) ? 1 : 0;\n            hRgnBlur = IntPtr.Zero;\n            fTransitionOnMaximized = 0;\n        }\n\n        public Region Region => Region.FromHrgn(hRgnBlur);\n\n        public bool TransitionOnMaximized {\n            get => fTransitionOnMaximized > 0;\n            set {\n                fTransitionOnMaximized = (value) ? 1 : 0;\n                dwFlags |= DWM_BB.TransitionOnMaximized;\n            }\n        }\n\n        public void SetRegion(Graphics graphics, Region region)\n        {\n            hRgnBlur = region.GetHrgn(graphics);\n            dwFlags |= DWM_BB.BlurRegion;\n        }\n    }\n\n    [StructLayout(LayoutKind.Sequential)]\n    public struct WinCompositionAttrData {\n        public DWMWINDOWATTRIBUTE Attribute;\n        public IntPtr Data;  //Will point to an AccentPolicy struct, where Attribute will be DWMWINDOWATTRIBUTE.AccentPolicy\n        public int SizeOfData;\n\n        public WinCompositionAttrData(DWMWINDOWATTRIBUTE attribute, IntPtr data, int sizeOfData)\n        {\n            Attribute = attribute;\n            Data = data;\n            SizeOfData = sizeOfData;\n        }\n    }\n\n    private static int GetBlurBehindPolicyAccentFlags()\n    {\n        int drawLeftBorder = 20;\n        int drawTopBorder = 40;\n        int drawRightBorder = 80;\n        int drawBottomBorder = 100;\n        return (drawLeftBorder | drawTopBorder | drawRightBorder | drawBottomBorder);\n    }\n\n    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969508(v=vs.85).aspx\n    [DllImport("dwmapi.dll")]\n    internal static extern int DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);\n\n    [DllImport("dwmapi.dll", PreserveSig = false)]\n    public static extern void DwmEnableComposition(CompositionAction uCompositionAction);\n\n    //https://msdn.microsoft.com/it-it/library/windows/desktop/aa969512(v=vs.85).aspx\n    [DllImport("dwmapi.dll")]\n    internal static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);\n\n    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969515(v=vs.85).aspx\n    [DllImport("dwmapi.dll")]\n    internal static extern int DwmGetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);\n\n    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa969524(v=vs.85).aspx\n    [DllImport("dwmapi.dll")]\n    internal static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);\n\n    [DllImport("User32.dll", SetLastError = true)]\n    internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WinCompositionAttrData data);\n\n    [DllImport("dwmapi.dll")]\n    internal static extern int DwmIsCompositionEnabled(ref int pfEnabled);\n\n    public static bool IsCompositionEnabled()\n    {\n        int pfEnabled = 0;\n        int result = DwmIsCompositionEnabled(ref pfEnabled);\n        return (pfEnabled == 1) ? true : false;\n    }\n\n    public static bool IsNonClientRenderingEnabled(IntPtr hWnd)\n    {\n        int gwaEnabled = 0;\n        int result = DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingEnabled, ref gwaEnabled, sizeof(int));\n        return gwaEnabled == 1;\n    }\n\n    public static bool WindowSetAttribute(IntPtr hWnd, DWMWINDOWATTRIBUTE attribute, int attributeValue)\n    {\n        int result = DwmSetWindowAttribute(hWnd, attribute, ref attributeValue, sizeof(int));\n        return (result == 0);\n    }\n\n    public static void Windows10EnableBlurBehind(IntPtr hWnd)\n    {\n        DWMNCRENDERINGPOLICY policy = DWMNCRENDERINGPOLICY.Enabled;\n        WindowSetAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);\n\n        AccentPolicy accPolicy = new AccentPolicy() {\n            AccentState = DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND,\n        };\n\n        int accentSize = Marshal.SizeOf(accPolicy);\n        IntPtr accentPtr = Marshal.AllocHGlobal(accentSize);\n        Marshal.StructureToPtr(accPolicy, accentPtr, false);\n        var data = new WinCompositionAttrData(DWMWINDOWATTRIBUTE.AccentPolicy, accentPtr, accentSize);\n\n        SetWindowCompositionAttribute(hWnd, ref data);\n        Marshal.FreeHGlobal(accentPtr);\n    }\n\n    public static bool WindowEnableBlurBehind(IntPtr hWnd)\n    {\n        DWMNCRENDERINGPOLICY policy = DWMNCRENDERINGPOLICY.Enabled;\n        WindowSetAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);\n\n        DWM_BLURBEHIND dwm_BB = new DWM_BLURBEHIND(true);\n        int result = DwmEnableBlurBehindWindow(hWnd, ref dwm_BB);\n        return result == 0;\n    }\n\n    public static bool WindowExtendIntoClientArea(IntPtr hWnd, MARGINS margins)\n    {\n        // Extend frame on the bottom of client area\n        int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);\n        return result == 0;\n    }\n\n    public static bool WindowBorderlessDropShadow(IntPtr hWnd, int shadowSize)\n    {\n        MARGINS margins = new MARGINS(0, shadowSize, 0, shadowSize);\n        int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);\n        return result == 0;\n    }\n\n    public static bool WindowSheetOfGlass(IntPtr hWnd)\n    {\n        MARGINS margins = new MARGINS();\n\n        //Margins set to All:-1 - Sheet Of Glass effect\n        margins.SheetOfGlass();\n        int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);\n        return result == 0;\n    }\n\n    public static bool WindowDisableRendering(IntPtr hWnd)\n    {\n        int ncrp = (int)DWMNCRENDERINGPOLICY.Disabled;\n        // Disable non-client area rendering on the window.\n        int result = DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, ref ncrp, sizeof(int));\n        return result == 0;\n    }\n}   //DWM\n
Run Code Online (Sandbox Code Playgroud)\n

这是一个示例结果,设置Form.BackColorMidnightBlue

\n

在此输入图像描述

\n
                Window Selected                              Windows Unselected\n
Run Code Online (Sandbox Code Playgroud)\n
\n

对其进行一些控制:

\n

在此输入图像描述

\n