针对“C# 无边框窗体边框阴影效果的简单实现”,以下是完整攻略:
标题
在文章开头设置一个一级标题,表示文章的主要内容。
# C# 无边框窗体边框阴影效果的简单实现
需求
在介绍实现方法之前,需要确定要实现的需求,指明要实现的功能。
无边框窗体边框阴影效果可以提升软件的美观度和用户体验度,所以是实现目标之一。
实现步骤
- 自定义窗口样式
首先需要将窗口的边框去掉,然后再设置窗口样式和位置。其中,窗口样式使用 WS_POPUP
,窗口位置使用 SetWindowPos
实现。
```csharp
int WS_POPUP = 0x800000;
int WS_VISIBLE = 0x10000000;
int SWP_NOSIZE = 0x0001;
int SWP_NOMOVE = 0x0002;
int SWP_NOZORDER = 0x0004;
int SWP_FRAMECHANGED = 0x0020;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style = WS_POPUP | WS_VISIBLE;
return cp;
}
}
public void SetShadowStyle()
{
SetWindowPos(this.Handle, HWND_TOPMOST, -20, -20, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
}
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
```
- 绘制阴影
窗口样式设置完成后,需要绘制窗口的阴影效果。可以使用 DrawShadow
方法实现。
```csharp
protected override void OnPaint(PaintEventArgs e)
{
DrawShadow(e.Graphics);
}
public void DrawShadow(Graphics g)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
using (GraphicsPath graphicsPath = new GraphicsPath())
{
graphicsPath.AddLines(new Point[] { new Point(30, 0), new Point(Width - 35, 0), new Point(Width - 1, 30),
new Point(Width - 1, Height - 35), new Point(Width - 35, Height - 1), new Point(30, Height - 1),
new Point(0, Height - 35), new Point(0, 30), new Point(30, 0) });
using (PathGradientBrush pathGradientBrush = new PathGradientBrush(graphicsPath))
{
pathGradientBrush.WrapMode = WrapMode.Clamp;
pathGradientBrush.CenterPoint = new PointF(-20, -20);
ColorBlend colorBlend = new ColorBlend(3);
colorBlend.Positions[0] = 0.0f;
colorBlend.Colors[0] = Color.FromArgb(0, 0, 0, 0);
colorBlend.Positions[1] = 0.1f;
colorBlend.Colors[1] = Color.FromArgb(80, 0, 0, 0);
colorBlend.Positions[2] = 1.0f;
colorBlend.Colors[2] = Color.FromArgb(80, 0, 0, 0);
pathGradientBrush.InterpolationColors = colorBlend;
Blend blend = new Blend
{
Factors = new float[] { 0f, 0.8f, 1f },
Positions = new float[] { 0f, 0.1f, 1f }
};
pathGradientBrush.Blend = blend;
g.FillPath(pathGradientBrush, graphicsPath);
}
}
}
```
- 事件处理
由于自定义的窗口不能进行拖动操作,需要通过事件处理进行实现。
```csharp
private Point offset;
private void TitleBar_MouseDown(object sender, MouseEventArgs e)
{
offset = new Point(e.X, e.Y);
}
private void TitleBar_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point currentScreenPos = PointToScreen(e.Location);
Location = new Point(currentScreenPos.X - offset.X, currentScreenPos.Y - offset.Y);
}
}
```
- 完整代码
```csharp
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace CSharpShadowForm
{
public partial class ShadowForm : Form
{
int WS_POPUP = 0x800000;
int WS_VISIBLE = 0x10000000;
int SWP_NOSIZE = 0x0001;
int SWP_NOMOVE = 0x0002;
int SWP_NOZORDER = 0x0004;
int SWP_FRAMECHANGED = 0x0020;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style = WS_POPUP | WS_VISIBLE;
return cp;
}
}
public void SetShadowStyle()
{
SetWindowPos(this.Handle, HWND_TOPMOST, -20, -20, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
}
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public ShadowForm(Form targetForm)
{
InitializeComponent();
Init(targetForm);
}
private void Init(Form targetForm)
{
Width = targetForm.Width + 60;
Height = targetForm.Height + 60;
TopLevel = true;
TopMost = true;
FormBorderStyle = FormBorderStyle.None;
BackColor = Color.Black;
Opacity = 0.24;
SetShadowStyle();
Location = new Point(targetForm.Location.X - 30, targetForm.Location.Y - 30);
targetForm.LocationChanged += new System.EventHandler(TargetForm_LocationChanged);
TitleBar.MouseDown += new MouseEventHandler(TitleBar_MouseDown);
TitleBar.MouseMove += new MouseEventHandler(TitleBar_MouseMove);
}
private void TitleBar_MouseDown(object sender, MouseEventArgs e)
{
offset = new Point(e.X, e.Y);
}
private void TitleBar_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point currentScreenPos = PointToScreen(e.Location);
Location = new Point(currentScreenPos.X - offset.X, currentScreenPos.Y - offset.Y);
}
}
private Point offset;
private void TargetForm_LocationChanged(object sender, System.EventArgs e)
{
Location = new Point(Owner.Location.X - 30, Owner.Location.Y - 30);
}
protected override void OnPaint(PaintEventArgs e)
{
DrawShadow(e.Graphics);
}
public void DrawShadow(Graphics g)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
using (GraphicsPath graphicsPath = new GraphicsPath())
{
graphicsPath.AddLines(new Point[] { new Point(30, 0), new Point(Width - 35, 0), new Point(Width - 1, 30), new Point(Width - 1, Height - 35),
new Point(Width - 35, Height - 1), new Point(30, Height - 1), new Point(0, Height - 35), new Point(0, 30), new Point(30, 0) });
using (PathGradientBrush pathGradientBrush = new PathGradientBrush(graphicsPath))
{
pathGradientBrush.WrapMode = WrapMode.Clamp;
pathGradientBrush.CenterPoint = new PointF(-20, -20);
ColorBlend colorBlend = new ColorBlend(3);
colorBlend.Positions[0] = 0.0f;
colorBlend.Colors[0] = Color.FromArgb(0, 0, 0, 0);
colorBlend.Positions[1] = 0.1f;
colorBlend.Colors[1] = Color.FromArgb(80, 0, 0, 0);
colorBlend.Positions[2] = 1.0f;
colorBlend.Colors[2] = Color.FromArgb(80, 0, 0, 0);
pathGradientBrush.InterpolationColors = colorBlend;
Blend blend = new Blend
{
Factors = new float[] { 0f, 0.8f, 1f },
Positions = new float[] { 0f, 0.1f, 1f }
};
pathGradientBrush.Blend = blend;
g.FillPath(pathGradientBrush, graphicsPath);
}
}
}
}
}
```
示例说明
以下是两条示例说明:
示例一
如果想要在窗口加载完成后添加阴影效果,可以使用以下代码。
private void Form_Load(object sender, EventArgs e)
{
ShadowForm shadowForm = new ShadowForm(this);
shadowForm.Show();
}
示例二
如果需要在拖动窗口时同时拖动阴影效果,可以在 TitleBar_MouseMove
方法中添加以下代码。
private void TitleBar_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point currentScreenPos = PointToScreen(e.Location);
ShadowForm.Location = new Point(currentScreenPos.X - offset.X - 30, currentScreenPos.Y - offset.Y - 30);
Location = new Point(currentScreenPos.X - offset.X, currentScreenPos.Y - offset.Y);
}
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 无边框窗体边框阴影效果的简单实现 - Python技术站