Drop Shadow On A Borderless WinForm

倾然丶 夕夏残阳落幕 提交于 2019-11-27 10:53:34

问题


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.

This is what I want..¬

Not this..¬


回答1:


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.




回答2:


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();     } } 



回答3:


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 



回答4:


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.



来源:https://stackoverflow.com/questions/16493698/drop-shadow-on-a-borderless-winform

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!