使用 GDI+ 创建非矩形窗体






4.80/5 (37投票s)
2004年12月23日
2分钟阅读

108002

3538
本文介绍了使用 GDI+ 创建非矩形窗体的方法。
引言
这是我在 CodeProject 上发表的第一篇文章,我在这里花费了大量时间阅读文章。请原谅我任何拼写错误,因为英语不是我的母语。
在本文中,我将向您展示创建非矩形窗体的不同方法,这将使您的应用程序更具吸引力,并且不会浪费您的时间,因为它是一项非常简单的任务。
背景
虽然我不知道如何使用 Visual Studio 6 创建非矩形窗体,但我相信这并非易事。它需要大量的 API 调用。但是使用 Visual Studio .NET,您会发现这非常容易,并且有预定义的步骤可以执行。有两种不同的方法
- 使用 Windows Forms 中的 transparency key 属性。
- 使用 GDI+ 技术
使用 Windows Forms 中的 transparency key 属性
这是一个简单的解决方案,只需按照以下步骤操作
- 将
FormBorderStyle
属性设置为None
(这将删除边框)。 - 创建一个位图,将其设置为窗体的背景图像。
- 用特定颜色(例如:黑色)填充您希望显示为透明的区域。
- 将
BackgroundImage
属性设置为您的位图。 - 将
TransparencyKey
属性设置为指定的颜色(在我们的示例中为黑色)。
因为我们删除了边框,您会发现我们无法关闭或移动我们的窗体,所以我们必须创建鼠标事件,我将在本文后面讨论。
如果这种方式不起作用并且您可以看到整个背景,请检查您显示器的颜色质量是否低于 32 位。如果您使用特定颜色更改 BackColor
属性并将 TransparencyKey
属性设置为相同的颜色,您会发现您的窗体消失了,因为这种方式取决于一些系统设置。我在 MSDN 上搜索了一种制作非矩形窗体的替代方法,我找到了我想要的。
使用 GDI+ 技术
这是一种简单的方法。它也依赖于 TransparencyKey
。步骤如下
- 将
FormBorderStyle
设置为None
- 使用指定的颜色设置
BackColor
属性 - 使用相同的颜色设置
TransparancyKey
属性 - 现在整个窗体都是透明的
- 然后使用
GraphicsPath
类指定窗体的可见区域 - 然后调用
SetClip
方法以使用GraphicsPath
区域替换裁剪区域 - 用颜色或图像填充该区域
// The namesapces used
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
然后,我们必须覆盖 onpaint
事件,该事件在必须重新绘制窗口时调用。
protected override void OnPaint(PaintEventArgs e)
{
// First we create a graphics object using
// the PiantEventArgs e that will use the form
Graphics grfx = e.Graphics;
// Make Antialiasing which avoid stepped
// look for circular path and curves you may
// use the SmoothingMode.AntiAlias
grfx.SmoothingMode = SmoothingMode.HighQuality;
// The GraphicsPath class is a sealed class
// that Represents a series of connected
// lines and curves used to close
// a path which will be tarnsparent
GraphicsPath grfxPath1 = new GraphicsPath();
// To make a circular form we will darw
// an ellipse that is bounded inside a square which
// will be simply a circle if it is bounded
// to a rectangle it will draw an ellipse
// i will make a form that is formed from 2 ellipses
Rectangle rec1 = new Rectangle(0,0,300,100);
grfxPath1.AddEllipse(rec1);
Rectangle rec2 = new Rectangle(120,99,60,40);
grfxPath1.AddEllipse(rec2);
// setclip Sets the clipping region of this
// Graphics object to the result of the specified
// operation combining the current clip region
// and the specified GraphicsPath object.
grfx.SetClip(grfxPath1,CombineMode.Replace);
// now we replace the clipping region with
// the region specified in the graphicspath
// we can fill this region with a color -even
// the color specified in the TransparensyKey-
// because the fill method is simply not detected by the TransparensyKey
Brush b = new SolidBrush(Color.Green);
grfx.FillEllipse(b,rec1);
grfx.FillEllipse(b,rec2);
// u may use the following 2 lines to put
// an image instead the last four lines
// which fill the form with a normal color
// note: the BackgrounImage can't be used because
// it is detected by the TransparensyKey
// Rectangle frmRectangle = new Rectangle(0,0,this.Width,this.Height);
// grfx.DrawImage(Image.FromFile("zerosones.jpg"), frmRectangle);
// then we may make a border to our from by using a thick pen
Pen p = new Pen(Color.Yellow,5f);
grfx.DrawPath(p,grfxPath1);
}
鼠标事件
因为我们删除了边框,所以我们无法移动我们的窗体,因此我们必须添加鼠标处理程序来替换默认值。
// points to hold the current position
// and the new position for the form and the mouse
Point MouseCurrrnetPos,MouseNewPos,formPos,formNewPos;
bool mouseDown=false;
private void Form1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
// when the mouse is down we must activate
// a flag to say that the left button is down
// and then store the current position
// of the mouse and the form and we will
// use these posotions to calculate the offset
// that must be added to the loaction
if(e.Button==MouseButtons.Left)
{
mouseDown = true;
MouseCurrrnetPos = Control.MousePosition;
formPos = Location;
}
}
// when the user release the mouse button we must update the flag
private void Form1_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if(e.Button==MouseButtons.Left)
mouseDown=false;
}
// when the mouse moves we get its new position
// then calculate the new location that the form
// should be moved to
// and then set the current position of the form
// and the mouse with the new ones
private void Form1_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if(mouseDown==true)
{
// get the position of the mouse in the screen
MouseNewPos=Control.MousePosition;
formNewPos.X=MouseNewPos.X-MouseCurrrnetPos.X+formPos.X;
formNewPos.Y=MouseNewPos.Y-MouseCurrrnetPos.Y+formPos.Y;
Location=formNewPos;
formPos=formNewPos;
MouseCurrrnetPos=MouseNewPos;
}
}
参考
- MSDN.