在无边框WinForm上投下阴影

我试图像第一张图片一样在整个表单周围留下阴影,除了那是WPF而不是WinForm。 现在我想在winform上放下相同的阴影。

这就是我想要的……

Windows Form Shadow

不是这个……

Windows Form Shadow

在WinForms中,您可以覆盖表单的受保护的CreateParams属性,并将CS_DROPSHADOW标志添加到类样式中。 例如:

 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 ... } 

但是,有几点需要注意……

  1. 此标志仅适用于顶级窗口。 在Win32中,这意味着重叠和弹出窗口。 它对子窗口(例如控件)没有影响。 我以为我记得在某个地方听说过这个限制已经从Windows 8中删除了,但我找不到确认这个的链接,我没有安装Windows 8用于测试目的。

  2. 用户可能完全禁用了此function。 如果是这样,无论你如何要求它们,你都不会得到阴影。 这是设计的。 您的应用程序不应尝试覆盖此请求。 您可以通过P /调用SystemParametersInfo函数并传递SPI_GETDROPSHADOW标志来确定是启用还是禁用SPI_GETDROPSHADOW

  3. Aero主题还为顶级窗口添加了阴影。 此效果与CS_DROPSHADOW是分开且不同的, 在启用Aero时有效。 对于单个窗口,无法关闭和打开它。 此外,由于Aero主题已从Windows 8中删除,因此它不会有这些阴影。

这是我的C#实现。 它与Al.Pertro相似,但你会注意到当你失去焦点并重新获得焦点时,阴影会重新粉刷自己。

我还添加了代码以允许鼠标拖动。

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

Humm ,,,刚刚通过代码,你会得到像这样的Windows 7 Drop Shadow >>> 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  _ Public Shared Function DwmExtendFrameIntoClientArea(ByVal hWnd As IntPtr, ByRef pMarInset As NativeStructs.MARGINS) As Integer End Function  _ Friend Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As Integer, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer End Function  _ 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 

据我所知,在WinForms中没有直接的方法。

相反,您可以按照以下步骤操作:

1)使用photoshop或任何其他工具创建具有所需阴影的图像。
2)使用此图像作为表单的背景图像。
3)将窗体的FormBorderStyle属性设置为None。
4)你完成了!
5)注意:确保以适当的格式(例如png)保存图像,以便投影效果起作用。