无边框表格Dropshadow

所以我有以下代码:

#region Dropshadow [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")] private static extern IntPtr CreateRoundRectRgn ( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse ); [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; public struct MARGINS { public int leftWidth; public int rightWidth; public int topHeight; public int bottomHeight; } protected override CreateParams CreateParams { get { m_aeroEnabled = CheckAeroEnabled(); CreateParams cp = base.CreateParams; if (!m_aeroEnabled) { cp.ClassStyle |= 0x00020000; } 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 0x0085: if (m_aeroEnabled) { int v = 2; DwmSetWindowAttribute(Handle, 2, ref v, 4); MARGINS margins = new MARGINS() { bottomHeight = 1, leftWidth = 0, rightWidth = 0, topHeight = 0 }; DwmExtendFrameIntoClientArea(Handle, ref margins); } break; default: break; } base.WndProc(ref m); } #endregion 

这使得使用GDI的Dropshadow。 然而,唯一的问题是,我必须让它在顶部保持1个像素的高度边框(它可以是任何边缘,只是顶部是我的应用程序最难注意到的)。

这使我的应用程序顶部的一行显着降低了观看体验。

有可能没有边框吗?

(bottomHeight = 1代码就是它的全部。如果我将它设置为0,topHeight为1,则该行将位于底部。将所有这些设置为0,根本不显示任何阴影。)

事实certificate,它与我的填充有关,我需要在至少1个边缘留下1个像素线为空以使Dropshadow工作。 我选择使用Padding制作1像素线,然后将顶部填充设置为1.这将线设置在顶部。 bottomHeight = 1根本不重要。 它就在那里,因为它至少需要其中一个非0。

如果我删除Padding和Top Line等。并且在CreateParams overide中,如果我删除启用aero的检查,它会显示类似下面的阴影: 在此处输入图像描述

这是一个Form类,它使用DWM渲染它的边框/阴影。

如上所述,您需要注册一个属性, DWMWINDOWATTRIBUTE和相关的策略DWMNCRENDERINGPOLICY ,将其值设置为Enabled。
然后使用DwmSetWindowAttribute()设置属性,并使用DwmExtendFrameIntoClientArea()DwmEnableBlurBehindWindow()等设置所需的效果。

所需的所有声明都在这里。

这是Form类(名为“Borderless”,在创造力的火花中)。
我试图让它看起来像你已发布的内容,以尽量减少“影响”。

Form是一个标准的WinForms表单, 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); } } 

这些都是所需的声明,以及其他可能有用的声明。
请注意,我只使用Win32 API的internal属性,这些API使用帮助程序方法调用。

这是一个部分类,因为Winapi类是一个广泛的类库。 您可以将其更改为您习惯的任何内容。

我建议保留Win32 API声明的[SuppressUnmanagedCodeSecurityAttribute]属性。

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