Borderless Form Dropshadow

前端 未结 2 621
攒了一身酷
攒了一身酷 2020-12-22 11:02

So I have the following code:

#region Dropshadow
[DllImport(\"Gdi32.dll\", EntryPoint = \"CreateRoundRectRgn\")]
private static extern IntPtr CreateRoundRect         


        
相关标签:
2条回答
  • 2020-12-22 11:11

    This is a Form class that uses DWM to render it's borders/shadow.

    As described, you need to register an Attribute, DWMWINDOWATTRIBUTE, and the related Policy, DWMNCRENDERINGPOLICY, settings it's value to Enabled.
    Then set the attribute with DwmSetWindowAttribute() and the desired effect with DwmExtendFrameIntoClientArea(), DwmEnableBlurBehindWindow() and so on.

    All the declarations needed are here.

    This is the Form class (named "Borderless", in a spark of creativity).
    I tried to make it look like what you already have posted, to minimize the "impact".

    The Form is a standard WinForms Form with FormBorderStyle = None.

    public partial class Borderless : Form
    {
        public Borderless() => InitializeComponent();
    
        protected override void OnHandleCreated(EventArgs e) {
            base.OnHandleCreated(e);
            WinApi.Dwm.DWMNCRENDERINGPOLICY Policy = WinApi.Dwm.DWMNCRENDERINGPOLICY.Enabled;
            WinApi.Dwm.WindowSetAttribute(this.Handle, WinApi.Dwm.DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)Policy);
            if (DWNCompositionEnabled()) { WinApi.Dwm.WindowBorderlessDropShadow(this.Handle, 2); }
            //if (DWNCompositionEnabled()) { WinApi.Dwm.WindowEnableBlurBehind(this.Handle); }
            //if (DWNCompositionEnabled()) { WinApi.Dwm.WindowSheetOfGlass(this.Handle); }
        }
    
        private bool DWNCompositionEnabled() => (Environment.OSVersion.Version.Major >= 6)
                                             ? WinApi.Dwm.IsCompositionEnabled()
                                             : false;
    
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case (int)WinApi.WinMessage.WM_DWMCOMPOSITIONCHANGED:
                    {
                        WinApi.Dwm.DWMNCRENDERINGPOLICY Policy = WinApi.Dwm.DWMNCRENDERINGPOLICY.Enabled;
                        WinApi.Dwm.WindowSetAttribute(this.Handle, WinApi.Dwm.DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)Policy);
                        WinApi.Dwm.WindowBorderlessDropShadow(this.Handle, 2);
                        m.Result = (IntPtr)0;
                    }
                    break;
                default:
                    break;
            }
            base.WndProc(ref m);
        }
    }
    


    These are all the declarations needed, plus others that might become useful.
    Note that I only use the internal attribute form Win32 APIs, which are called using helpr methods.

    It's a partial class because the Winapi class is a extensive class library. You can change it to whatever you are used to.

    I suggest to keep the [SuppressUnmanagedCodeSecurityAttribute] attribute for the Win32 APIs declarations.

    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
            }
    
            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.
            };
    
            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;
                }
            }
    
    
            [SuppressUnmanagedCodeSecurityAttribute]
            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("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 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);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-22 11:28

    I set the bottomHeight to 3, and I found that the border height was included in the form size (the form's size didn't change). So I set a BackgroundImage to this form, and the border was hidden by the image.

    0 讨论(0)
提交回复
热议问题