Drop Shadow On A Borderless WinForm

后端 未结 5 1934
暖寄归人
暖寄归人 2020-12-08 05:38

I\'m trying to drop a shadow around the whole form just like the first picture, except that that is a WPF, not a WinForm. now I want to drop the same shadow on a winform.

相关标签:
5条回答
  • 2020-12-08 05:52

    I already answered it here: Drop shadow on Borderless Winform-No flicker or disappearance

    Here's my answer:

    Pls try the below steps and revert back for any errors:

    Add the below code to a new code file named DropShadow.cs;

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Core
    {
        public class DropShadow
        {
            #region Shadowing
    
            #region Fields
    
            private bool _isAeroEnabled = false;
            private bool _isDraggingEnabled = false;
            private const int WM_NCHITTEST = 0x84;
            private const int WS_MINIMIZEBOX = 0x20000;
            private const int HTCLIENT = 0x1;
            private const int HTCAPTION = 0x2;
            private const int CS_DBLCLKS = 0x8;
            private const int CS_DROPSHADOW = 0x00020000;
            private const int WM_NCPAINT = 0x0085;
            private const int WM_ACTIVATEAPP = 0x001C;
    
            #endregion
    
            #region Structures
    
            [EditorBrowsable(EditorBrowsableState.Never)]
            public struct MARGINS
            {
                public int leftWidth;
                public int rightWidth;
                public int topHeight;
                public int bottomHeight;
            }
    
            #endregion
    
            #region Methods
    
            #region Public
    
            [DllImport("dwmapi.dll")]
            [EditorBrowsable(EditorBrowsableState.Never)]
            public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
    
            [DllImport("dwmapi.dll")]
            [EditorBrowsable(EditorBrowsableState.Never)]
            public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
    
            [DllImport("dwmapi.dll")]
            [EditorBrowsable(EditorBrowsableState.Never)]
            public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
    
            [EditorBrowsable(EditorBrowsableState.Never)]
            public static bool IsCompositionEnabled()
            {
                if (Environment.OSVersion.Version.Major < 6) return false;
    
                bool enabled;
                DwmIsCompositionEnabled(out enabled);
    
                return enabled;
            }
    
            #endregion
    
            #region Private
    
            [DllImport("dwmapi.dll")]
            private static extern int DwmIsCompositionEnabled(out bool enabled);
    
            [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
            private static extern IntPtr CreateRoundRectRgn
            (
                int nLeftRect,
                int nTopRect,
                int nRightRect,
                int nBottomRect,
                int nWidthEllipse,
                int nHeightEllipse
             );
    
            private bool CheckIfAeroIsEnabled()
            {
                if (Environment.OSVersion.Version.Major >= 6)
                {
                    int enabled = 0;
                    DwmIsCompositionEnabled(ref enabled);
    
                    return (enabled == 1) ? true : false;
                }
                return false;
            }
    
            #endregion
    
            #region Overrides
    
            public void ApplyShadows(Form form)
            {
                var v = 2;
    
                DwmSetWindowAttribute(form.Handle, 2, ref v, 4);
    
                MARGINS margins = new MARGINS()
                {
                    bottomHeight = 1,
                    leftWidth = 0,
                    rightWidth = 0,
                    topHeight = 0
                };
    
                DwmExtendFrameIntoClientArea(form.Handle, ref margins);
            }
    
            #endregion
    
            #endregion
    
            #endregion
        }
    }
    

    In your form, add this line below InitializeComponent();

    (new Core.DropShadow()).ApplyShadows(this);
    
    0 讨论(0)
  • 2020-12-08 06:05

    Humm ,,, Just past the code and you will get the windows 7 Drop Shadow like this >>> http://marcin.floryan.pl/wp-content/uploads/2010/08/WPF-Window-native-shadow.png

    Imports System.Runtime.InteropServices
    
    Public Class IMSS_SplashScreen
        Private aeroEnabled As Boolean
        Protected Overrides ReadOnly Property CreateParams() As CreateParams
            Get
                CheckAeroEnabled()
                Dim cp As CreateParams = MyBase.CreateParams
                If Not aeroEnabled Then
                    cp.ClassStyle = cp.ClassStyle Or NativeConstants.CS_DROPSHADOW
                    Return cp
                Else
                    Return cp
                End If
            End Get
        End Property
        Protected Overrides Sub WndProc(ByRef m As Message)
            Select Case m.Msg
                Case NativeConstants.WM_NCPAINT
                    Dim val = 2
                    If aeroEnabled Then
                        NativeMethods.DwmSetWindowAttribute(Handle, 2, val, 4)
                        Dim bla As New NativeStructs.MARGINS()
                        With bla
                            .bottomHeight = 1
                            .leftWidth = 1
                            .rightWidth = 1
                            .topHeight = 1
                        End With
                        NativeMethods.DwmExtendFrameIntoClientArea(Handle, bla)
                    End If
                    Exit Select
            End Select
            MyBase.WndProc(m)
        End Sub
        Private Sub CheckAeroEnabled()
            If Environment.OSVersion.Version.Major >= 6 Then
                Dim enabled As Integer = 0
                Dim response As Integer = NativeMethods.DwmIsCompositionEnabled(enabled)
                aeroEnabled = (enabled = 1)
            Else
                aeroEnabled = False
            End If
        End Sub
    End Class
    Public Class NativeStructs
        Public Structure MARGINS
            Public leftWidth As Integer
            Public rightWidth As Integer
            Public topHeight As Integer
            Public bottomHeight As Integer
        End Structure
    End Class
    Public Class NativeMethods
        <DllImport("dwmapi")> _
        Public Shared Function DwmExtendFrameIntoClientArea(ByVal hWnd As IntPtr, ByRef pMarInset As NativeStructs.MARGINS) As Integer
        End Function
        <DllImport("dwmapi")> _
        Friend Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As Integer, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
        End Function
        <DllImport("dwmapi.dll")> _
        Public Shared Function DwmIsCompositionEnabled(ByRef pfEnabled As Integer) As Integer
        End Function
    End Class
    Public Class NativeConstants
        Public Const CS_DROPSHADOW As Integer = &H20000
        Public Const WM_NCPAINT As Integer = &H85
    End Class
    
    0 讨论(0)
  • 2020-12-08 06:10

    In WinForms, you can just override the form's protected CreateParams property and add the CS_DROPSHADOW flag to the class styles. For example:

    public class ShadowedForm : Form {
        protected override CreateParams CreateParams {
            get {
                const int CS_DROPSHADOW = 0x20000;
                CreateParams cp = base.CreateParams;
                cp.ClassStyle |= CS_DROPSHADOW;
                return cp;
            }
        }
    
        // ... other code ...
    }
    

    But, a couple of caveats…

    1. This flag works only on top-level windows. In Win32-speak, that means overlapped and popup windows. It has no effect on child windows (e.g. controls). I thought I remembered hearing somewhere that this limitation had been removed from Windows 8, but I can't find a link confirming this and I don't have Windows 8 installed for testing purposes.

    2. It is possible that the user has disabled this feature altogether. If so, you won't get drop shadows, no matter how you ask for them. That's by design. Your application should not try and override this request. You can determine whether drop shadows are enabled or disabled by P/Invoking the SystemParametersInfo function and passing the SPI_GETDROPSHADOW flag.

    3. The Aero theme also adds shadows to top-level windows. This effect is separate and distinct from CS_DROPSHADOW, and works only when Aero is enabled. There's no way to turn it off and on for individual windows. Moreover, since the Aero theme has been removed from Windows 8, it won't ever have these shadows.

    0 讨论(0)
  • 2020-12-08 06:14

    Here's my C# implementation. It's similar to Al. Petro's, but you'll notice that when you lose focus and regain focus, the shadow repaints itself.

    I've also added code to allow mouse-dragging.

    public partial class Form1: Form
    {
        [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
        private static extern IntPtr CreateRoundRectRgn
        (
            int nLeftRect, // x-coordinate of upper-left corner
            int nTopRect, // y-coordinate of upper-left corner
            int nRightRect, // x-coordinate of lower-right corner
            int nBottomRect, // y-coordinate of lower-right corner
            int nWidthEllipse, // height of ellipse
            int nHeightEllipse // width of ellipse
         );        
    
        [DllImport("dwmapi.dll")]
        public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
    
        [DllImport("dwmapi.dll")]
        public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
    
        [DllImport("dwmapi.dll")]
        public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
    
        private bool m_aeroEnabled;                     // variables for box shadow
        private const int CS_DROPSHADOW = 0x00020000;
        private const int WM_NCPAINT = 0x0085;
        private const int WM_ACTIVATEAPP = 0x001C;
    
        public struct MARGINS                           // struct for box shadow
        {
            public int leftWidth;
            public int rightWidth;
            public int topHeight;
            public int bottomHeight;
        }
    
        private const int WM_NCHITTEST = 0x84;          // variables for dragging the form
        private const int HTCLIENT = 0x1;
        private const int HTCAPTION = 0x2;
    
        protected override CreateParams CreateParams
        {
            get
            {
                m_aeroEnabled = CheckAeroEnabled();
    
                CreateParams cp = base.CreateParams;
                if (!m_aeroEnabled)
                    cp.ClassStyle |= CS_DROPSHADOW;
    
                return cp;
            }
        }
    
        private bool CheckAeroEnabled()
        {
            if (Environment.OSVersion.Version.Major >= 6)
            {
                int enabled = 0;
                DwmIsCompositionEnabled(ref enabled);
                return (enabled == 1) ? true : false;
            }
            return false;
        }
    
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_NCPAINT:                        // box shadow
                    if (m_aeroEnabled)
                    {
                        var v = 2;
                        DwmSetWindowAttribute(this.Handle, 2, ref v, 4);
                        MARGINS margins = new MARGINS()
                        {
                            bottomHeight = 1,
                            leftWidth = 1,
                            rightWidth = 1,
                            topHeight = 1
                        };
                        DwmExtendFrameIntoClientArea(this.Handle, ref margins);
    
                    }
                    break;
                default:
                    break;
            }
            base.WndProc(ref m);
    
            if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCLIENT)     // drag the form
                m.Result = (IntPtr)HTCAPTION;
    
        }
    
        public Form1()
        {
            m_aeroEnabled = false;
    
            this.FormBorderStyle = FormBorderStyle.None;
    
            InitializeComponent();
        }
    }
    
    0 讨论(0)
  • 2020-12-08 06:15

    As far as I know, there is no direct way of doing this in WinForms.

    Instead, you can follow this step by step:

    1) Create an image having the desired drop shadow using photoshop or any other tool.
    2) Use this image as background image of your form.
    3) Set FormBorderStyle property of the form to None.
    4) You are done!
    5) Note: Make sure to save the image in proper format(such as png) so that the drop shadow effect could work.

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