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#、VB.NET实现复杂的二进制操作

    让我先给出这个攻略的大纲: 引言 要解决的问题 C#和VB.NET实现二进制操作的基础知识 通过位运算实现的示例 通过位图操作实现的示例 总结 1. 引言 在使用C#或VB.NET编程时,我们难免需要进行一些复杂的二进制操作,例如位运算、位图操作等等。本篇攻略就是为了帮助你完整地解决这些问题。 2. 要解决的问题 我们需要解决的问题是,如何在C#或VB.NE…

    C# 2023年6月6日
    00
  • C# 输出参数out问题

    当我们在C#中使用方法时,有时需要从方法中返回多个值。但是,C#中的方法只能够返回单个值。为了解决这一问题,我们可以使用输出参数(out parameter)。在这篇攻略中,我会详细讲解“C# 输出参数out问题”的相关内容。 输出参数(out parameter)是什么? 输出参数是C#中一种特殊的参数类型,用于从方法中返回多个值。和普通参数不同,输出参数…

    C# 2023年6月7日
    00
  • 十分钟打造AutoComplete自动完成效果代码

    AutoComplete自动完成效果是一种常见的交互式UI组件,它可以帮助用户快速找到他们正在寻找的内容。本文将提供详解如何在十分钟内打造AutoComplete自动完成效果的完整攻略,包括使用jQuery UI的autocomplete方法、使用Bootstrap的typeahead插件等。同时,本文还提供两个示例,演示如何使用jQuery UI和Boot…

    C# 2023年5月15日
    00
  • WPF实现钟表效果

    下面我会为你详细讲解“WPF实现钟表效果”的完整攻略。 一、准备工作 1. 新建WPF应用程序 首先,我们需要新建一个WPF应用程序。 2. 引用PresentationCore、PresentationFramework、WindowsBase三个文件 在新建的WPF应用程序中,我们需要添加 PresentationCore、PresentationFra…

    C# 2023年6月1日
    00
  • C#程序加密工具.Net Reactor详细教程

    C#程序加密工具.Net Reactor详细教程 什么是.Net Reactor? .Net Reactor是一个针对C#程序的加密工具,可以将C#源代码编译成.NET程序集,并且对程序进行加密、混淆等保护操作,以防止程序的源代码被泄露或盗用。 如何使用.Net Reactor? 下载与安装 首先需要在官网上下载并安装.Net Reactor。安装时需要输入…

    C# 2023年5月31日
    00
  • C#实现随机数产生类实例

    C# 中随机数的生成可以使用 Random 类来实现。以下是实现随机数产生类实例的攻略: 步骤一:引入 Random 类 using System; 在代码文件开头引入 Random 类,通过使用 using 关键词来使 Random 类成为项目中可使用的类。 步骤二:在类中声明 Random 类实例 Random random = new Random()…

    C# 2023年6月7日
    00
  • ASP.Net MVC 布局页、模板页使用方法详细介绍

    下面我将详细讲解“ASP.Net MVC布局页、模板页使用方法详细介绍”的完整攻略,过程中将包含两个示例的说明。 ASP.Net MVC布局页 ASP.Net MVC布局页用于定义网站的整体布局,例如头部、底部、导航等元素,以及将内容区域占据的html、css进行分离。 具体实现步骤如下: 创建一个布局页 在MVC项目的Views/Shared文件夹下,右键…

    C# 2023年5月31日
    00
  • ajax跨域调用webservice的实现代码

    要实现ajax跨域调用webservice,我们需要使用JSONP或CORS技术。JSONP是一种通过动态创建script标签来实现跨域请求的技术,而CORS是一种通过在服务器端设置响应头来实现跨域请求的技术。本文将提供详解“ajax跨域调用webservice的实现代码”的完整攻略,包括如何使用JSONP和CORS技术实现跨域请求。 使用JSONP实现跨域…

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