C# 无边框窗体边框阴影效果的简单实现

针对“C# 无边框窗体边框阴影效果的简单实现”,以下是完整攻略:

标题

在文章开头设置一个一级标题,表示文章的主要内容。

# C# 无边框窗体边框阴影效果的简单实现

需求

在介绍实现方法之前,需要确定要实现的需求,指明要实现的功能。

无边框窗体边框阴影效果可以提升软件的美观度和用户体验度,所以是实现目标之一。

实现步骤

  1. 自定义窗口样式

首先需要将窗口的边框去掉,然后再设置窗口样式和位置。其中,窗口样式使用 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);
```

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

       }
   }

}
```

  1. 事件处理

由于自定义的窗口不能进行拖动操作,需要通过事件处理进行实现。

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

  1. 完整代码

```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技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • 深入理解C#中常见的委托

    深入理解C#中常见的委托 委托的定义 委托(Delegate)是一种类型,它可以封装一个方法,使该方法像一个对象实例一样被传递。委托可以像其他任何对象一样进行实例化和调用,其实质是把方法作为参数进行传递和执行。在C#当中,定义委托类型需要使用delegate关键字: delegate void MyDelegate(int param); 以上代码定义了一个…

    C# 2023年5月31日
    00
  • C#实现写系统日志的方法

    首先,我们需要了解什么是系统日志。 系统日志(Syslog) 是一种由大多数操作系统和一些网络设备所产生和使用的标准化的日志记录方式,通常用于记录系统事件以及系统性能数据等,以便于系统管理员进行故障诊断和维护工作。 在 C# 中,我们可以通过 System.Diagnostics 命名空间下的 EventLog 类来记录系统日志。 以下是实现 C# 写系统日…

    C# 2023年5月15日
    00
  • C#下载歌词文件的同步和异步方法

    下面是关于C#下载歌词文件的同步和异步方法的完整攻略: 1. 同步方法: 1.1 首先,我们需要引入System.Net命名空间下的WebClient类。 WebClient类可以实现简单的HTTP协议,我们可以通过它来下载歌词文件。 1.2 接下来,我们可以使用DownloadFile方法实现下载。 DownloadFile方法有两个参数,第一个参数为待下…

    C# 2023年5月31日
    00
  • C#在LINQ中使用GroupBy

    接下来我将为你讲解C#在LINQ中使用GroupBy的完整攻略。 1. 概述 在LINQ中,我们可以使用GroupBy方法对数据进行分组,GroupBy方法返回一个IEnumerable类型的集合,其中TKey是分组的条件,TSource是分组的元素。在Grouping中,有一个Key属性,用于获取当前分组的键。在分组之后,我们还可以使用Aggregate、…

    C# 2023年6月1日
    00
  • C# 输出字符串到文本文件中的实现代码

    下面是在 C# 中输出字符串到文本文件中的实现代码攻略: 1. 创建文件并写入字符串 代码实现 using System.IO; // 定义字符串变量 string str = "hello world!"; // 创建一个文件流 FileStream fs = new FileStream("output.txt",…

    C# 2023年5月31日
    00
  • Web.config 和 App.config 的区别分析

    Web.config 和 App.config 是 .NET 框架中用于配置应用程序的两个重要文件。它们都是XML格式的配置文件,可以用来存储应用程序的各种配置信息,如数据库连接字符串、应用程序设置、日志级别等。 Web.config 是ASP.NET网站的配置文件,可以存储网站中所有应用程序的设置信息,包括安全性、会话状态、信任级别、httpModules…

    C# 2023年5月31日
    00
  • .NET使用DinkToPdf将HTML转成PDF的示例代码

    让我来给您详细讲解下“.NET使用DinkToPdf将HTML转成PDF的示例代码”的攻略吧。 什么是DinkToPdf DinkToPdf是一个开源的跨平台库,可以将HTML转换为PDF文档。它使用WKHtmlToPdf底层转换引擎,支持Windows,Linux和MacOS。 安装DinkToPdf 要使用DinkToPdf,您需要将它作为NuGet包添…

    C# 2023年6月3日
    00
  • C#代码延时的几种实现

    针对C#代码延时的实现,我们可以采用以下几种方法: 1.使用Thread.Sleep方法 Thread.Sleep方法是C#中比较常用的一种延时实现方式。这个方法可以使程序“休眠”一定的时间。下面是一个示例,演示了通过Thread.Sleep方法实现延时的代码: using System; using System.Threading; class Prog…

    C# 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部