我试图在整个表单周围添加阴影,就像第一张图片一样,只不过那是 WPF,而不是 WinForm。现在我想在 winform 上放置相同的阴影。
这就是我想要的..←
不是这个..←
(来源:codeproject.com)
在 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 ...
}
但是,有一些注意事项......
此标志仅适用于顶级窗口。在 Win32 语言中,这意味着重叠窗口和弹出窗口。它对子窗口(例如控件)没有影响。我想我记得在某处听说过 Windows 8 已删除此限制,但我找不到确认这一点的链接,而且我没有安装 Windows 8 进行测试。
用户可能完全禁用了此功能。如果是这样,无论您如何要求它们,您都不会得到阴影。这是设计使然。您的应用程序不应尝试覆盖此请求。您可以通过 P/调用
SystemParametersInfo
函数并传递 SPI_GETDROPSHADOW
标志来确定是否启用或禁用阴影。Aero 主题还为顶层窗口添加了阴影。此效果与
CS_DROPSHADOW
是独立且不同的,且仅在启用 Aero 时才起作用。无法为各个窗口关闭和打开它。此外,由于 Aero 主题已从 Windows 8 中删除,因此它永远不会有这些阴影。 这是我的 C# 实现。这和艾尔很相似。 Petro 的,但你会注意到,当你失去焦点并重新获得焦点时,阴影会重新绘制自己。
我还添加了允许鼠标拖动的代码。
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();
}
}
嗯,,,只要通过代码,你就会得到 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
<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
我已经在这里回答过: 在无边框Winform上添加阴影-无闪烁或消失
这是我的回答:
请尝试以下步骤并恢复任何错误:
将以下代码添加到名为 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
}
}
在您的表单中,在 InitializeComponent(); 下面添加此行;
(new Core.DropShadow()).ApplyShadows(this);
不过,我还是建议切换到 WPF。我本人在很长一段时间内都是 WinForms 的用户,但是 WPF 在设计用户界面方面提供了更好的灵活性。您还可以自己自定义所有控件,无需任何框架或包。学习 WPF 确实需要一些时间,但这是值得的。
据我所知,在 WinForms 中没有直接的方法来做到这一点。
相反,您可以按照以下步骤操作:
1) 使用 Photoshop 或任何其他工具创建具有所需投影的图像。
2) 使用此图像作为表单的背景图像。
3) 将表单的 FormBorderStyle 属性设置为 None。
4)你完成了!
5) 注意:请确保以正确的格式保存图像(例如 png),以便投影效果发挥作用。