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日

相关文章

  • asp.net ubb使用代码

    当我们在开发一个网站或者一个论坛系统时,通常都需要使用 UBB(ultra bulletin board) 编辑器。在 ASP.NET 中,使用 UBB 编辑器可以轻松实现文字编辑、图片上传、表情等功能。而如何使用 ASP.NET 代码实现 UBB 编辑器的功能呢?下面是一个完整的攻略。 步骤一:引用 UBB 控件 首先,在 ASP.NET 项目中,我们需要…

    C# 2023年5月31日
    00
  • C#中list用法实例

    下面是关于C#中List用法的完整攻略。 什么是List 在C#语言中,List是指一个元素列表,也称为动态数组或无限长数组。它允许您动态添加或删除元素,以及在列表中访问特定元素。 如何创建List 我们可以使用List的构造函数来创建List对象。我们可以选择在构造函数中传递有关该List对象的信息,例如其初始容量: // 创建一个新的List对象 Lis…

    C# 2023年5月31日
    00
  • C#基于SQLiteHelper类似SqlHelper类实现存取Sqlite数据库的方法

    一、背景介绍SQLite是一个轻量级的关系型数据库,具有体积小,速度快,操作简便,易于集成等优点,在嵌入式设备,移动设备及桌面应用程序等方面得到广泛使用。C#语言作为一个跨平台的编程语言,在各个领域的应用也十分广泛,同时也提供了SQLite数据库的连接方式,提供SQLite连接C#的API。虽然C#提供了一些SQLite的API,但是操作SQLite数据库仍…

    C# 2023年5月31日
    00
  • C#中单例的实现方法

    来讲一下C#中单例的实现方法吧。 什么是单例模式? 在软件开发中,单例模式是一种常见的设计模式。它保证一个类只有一个实例存在,并提供一个全局访问点。 单例模式应用的场景很多,比如线程池、数据库连接池等,这里不再赘述。接下来我们来看一下C#中单例的实现方法。 单例模式的实现思路 实现单例模式的关键点在于控制对象的创建过程,并且对外提供全局唯一的访问点。按照这个…

    C# 2023年6月6日
    00
  • C#之字符串截取–Regex.Match使用

    C#之字符串截取–Regex.Match使用 在C#中,字符串截取是一项常见操作。Regex.Match()方法提供了一种强大的方式来根据正则表达式截取和匹配字符串。本文将介绍Regex.Match()方法的使用方法,包括声明、基本语法和两条示例说明。 声明 public static System.Text.RegularExpressions.Matc…

    C# 2023年6月6日
    00
  • 使用C#实现Windows组和用户管理的示例代码

    对于“使用C#实现Windows组和用户管理”的示例代码,我们需要先了解一些相关知识。Windows操作系统中,Group是一组用户的集合,User是系统中的个人用户。在.NET Framework中,我们可以使用System.DirectoryServices命名空间提供的类来进行Windows组和用户管理。下面是一个完整的攻略及两条示例: 第一步:添加S…

    C# 2023年5月15日
    00
  • 详解JAVA调用WCF服务的示例代码

    Java和WCF都是用于构建分布式应用程序的技术。Java可以通过调用WCF服务来实现与.NET平台的通信。本文将详细讲解如何使用Java调用WCF服务的示例代码,并提供两个示例。 1. 使用Java调用WCF服务的示例代码 以下是使用Java调用WCF服务的示例代码: import java.net.URL; import javax.xml.namesp…

    C# 2023年5月15日
    00
  • .NET使用.NET Core CLI开发应用程序

    .NET使用.NET Core CLI开发应用程序攻略 在本攻略中,我们将详细介绍如何使用.NET Core CLI开发应用程序。我们将会涵盖以下内容: 安装.NET Core SDK 创建.NET Core应用程序 编写代码 构建和运行应用程序 示例说明 1. 安装.NET Core SDK 在开始之前,您需要安装.NET Core SDK。您可以从官方网…

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