如何创建非矩形的windows窗体(c#,net)
在过去,创建一个非矩形的窗体是一件非常耗时耗力的过程,过去涉及到API的调用和大量的变成精力(在MFC或WIN32中)。现在不用再这样了。
注意:这个过程涉及到大量的图形处理,因此,不同的计算机根据内存和图形卡的不同执行的效能也有所不同。当程序涉及到自定义绘制的时候,总是应该在不同的视频卡上进行测试,以确保在部署给用户之后获得满意的性能。
创建非矩形窗体的过程有两个部分:创建一个形状窗体和编写程序逻辑以实现窗体的移动和关闭。第二个步骤是必须的,因为使用自定义形状的窗体没有标题栏,因此标题栏的功能没有被继承下来,例如移动窗体,关闭等功能。因此,有必要编写代码去实现这些功能。
要创建一个非矩形的窗体,分三步:
1创建一个位图,作为窗体的表面(另外,你可以对矩形进行裁切,裁切出你希望的形状)。
2创建一个windows程序项目,在它的属性设置中去除标题栏,使用位图作为这个状体的背景。
3编写代码实现标题栏的功能,如移动和关闭窗体。
创建一个一定形状的窗体
1创建一个非矩形的位图,位图的非矩形部分与背景使用不同的颜色,使用你喜欢的绘制方式。这个位图最终绘制到你的窗体之上,确保绘制的足够大以便使用。
/注释
:因为背景色的部分就是将被设置为透明的部分,背景透明,那么非矩形部分就形成一个非矩形的窗口了
/收割者
2在visual sutido中,创建一个新的windows程序项目。
3在属性窗口中:
a.设置FormBorderStyle属性为None。
这个属性可以移除标题栏。(它也移除了标题栏所提供的功能,包括移动和关闭窗体,然而,这个缺陷在代码中很容易修复)。
b.设置BackgroundImage属性为你之前创建的位图。不必将这个文件添加到项目系统中;这会在你指定它为背景图像的时候自动完成。这个属性设置位图图像作为窗体的背景(当配合TransparencyKey属性使用的时候,这个属性就定义了窗体的形状)
c.为位图文件的背景色设置TransparencyKey属性。
提示
属性的设置也可以通过代码的方式实现,下面的例子,我就是使用代码的方式实现的
收割者
这个属性告诉程序,你想要你的窗体的哪个部分不显示。注意:显示器的颜色位深大于24位可能会使窗体本身应该透明的部分出现显示问题。为了避免这个问题,应确保在显示控制面板上显示器的显示位深小于等于24位。当开发程序使用了透明性功能的时候,要记住提示用户注意这个问题。
编写代码关闭窗体
1添加一个BUTTON控件
2添加代码,让用户通过调用它Close方法关闭窗体
下面的代码展示了你可以添加按钮,当点击的时候,就会关闭窗体。
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
this.Button1.Click += new System.EventHandler(this.button1_Click);
///说明
一般这个不用手动添加,通过窗体设计器,在窗体设计器上添加一个按钮,然后双击这个按钮,就可以添加处理代码。
//收割者
编写代码移动窗体(可选)
1创建一个过程当窗体被拖动的时候移动窗体。编写像类似下面的代码创建一个新的Point对象。当你需要计算移动多少的时候会用到这个对象。IsMouseDown字段用于跟踪用户是否一直按着鼠标。窗体只有在鼠标按下的时候拖动才移动窗体。
private Point mouseOffset;
private bool isMouseDown = false;
2为窗体的鼠标按下事件创建处理程序。在这个处理程序中,添加代码允许用户在窗体的任意地方点击拖动它。
编写类似如下代码,根据鼠标指针的当前位置,将坐标分配给mouseOffset变量。在下面的代码中,要注意偏移位置计算是使用关于边框大小( FrameBorderSize.Width)和标题栏的高度( CaptionHeight).的系统信息进行的。当测量偏移的时候这些都应该考虑进去,因为有些测量使用的是客户区坐标,有的是屏幕坐标。因此偏移就等于边框加上宽度加上标题栏的高度,再加上窗体客户区内的偏移。
private void MYFORM_MouseDown(object sender, MouseEventArgs e)
{
int xOffset;
int yOffset;
if (e.Button == MouseButtons.Left)
{
xOffset = -e.X ;
yOffset = -e.Y ;
mouseOffset = new Point(xOffset, yOffset);
isMouseDown = true;
}
}
/注:
由于我实现已经将边框和标题栏去掉,这里设置鼠标新位置的时候,我没有加上它们的值。而是直接使用的鼠标位置值。
收割者
为了确保添加的代码被事件调用,使用类似如下代码:this.MouseDown += new
System.Windows.Forms.MouseEventHandler
(this.MYFORM_MouseDown);
3为鼠标的移动事件添加事件处理
编写类似如下代码。当鼠标左键按下并拖动,窗体的Location(位置)属性就是窗体的新的位置。
private void MYFORM_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (isMouseDown)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouseOffset.X, mouseOffset.Y);
Location = mousePos;
}
}
为了确保添加的代码被事件调用,使用类似如下代码:
this.MouseMove += new
System.Windows.Forms.MouseEventHandler
(this.MYFORM_MouseMove);
创建MouseUp事件(鼠标弹起)。键入类似如下代码。
private void MYFORM_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
// Changes the isMouseDown field so that the form does
// not move unless the user is pressing the left mouse button.
if (e.Button == MouseButtons.Left)
{
isMouseDown = false;
}
}
为了保证添加的代码被事件调用。添加以下类似代码:
this.MouseUp += new
System.Windows.Forms.MouseEventHandler
(this.MYFORM_MouseUp);
下面在时间指示器来说明这个例子。我添加一个TextBox控件,用来显示当前的本地之间,另外添加一个Timer,设置间隔时间为1000毫秒发送一个事件,我添加一个时间处理程序ShowTimer来显示当前的时间。在UI设计器中,如下:
然后我处理Load事件,这个事件在窗口显示出来被处理,这样,我们就可以在这里设置窗口属性,控件的大小和位置等等信息。代码如下:
在这个地方,我设置了建立非矩形窗口时的各种属性设置和资源准备。属性也可以在属性页中设置,也可以像这样,使用代码进行设置。
完成之后,效果如下:
这样一个时间指示器就完成了!!,而我使用的位图呢,是这样的:
而我设置的透明颜色为白色,因此,只要是白色的地方就变成了透明的了。剩下的圆形就是窗口的形状。这也就是产生不规整窗口(非矩形窗口)的原理。这和在MFC和win32下的原理不同,感兴趣中可以参考我的博客文章:
本文代码:http://download.csdn.net/detail/xinzhiyounizhiyouni/7086873
本文更多相关知识:
http://www.panshy.com/article/Sort_Desktop/UI/2014-03-23/2471.php