没有合适的资源?快使用搜索试试~ 我知道了~
从Windows操作系统诞生的第一天开始,所有的窗口都是矩形的。但是,打破这一戒规标新出异的软件正越来越多,即使是Microsoft这个矩形窗体的鼻祖,也开始使用不规则的异形窗体,WindowsMediaPlayer就是一个例子。可惜的是,构造异形窗体向来不是一件轻松的事情,不过现在不同了!有了.NET框架特别是WindowsForms包,即使构造复杂的窗体形状也变得轻而易举。 既然已经提到MediaPlayer,那就继续用它作为例子说明吧。MediaPlayer运用了许多特殊的技术,足以作为典型的范例。想必大家的Windows系统上都安装了MediaPlayer,你可以按照本文的说明马上打
资源推荐
资源详情
资源评论
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![thumb](https://img-home.csdnimg.cn/images/20210720083646.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/release/download_crawler_static/15051435/bg1.jpg)
用用VS.NET构造异形窗体构造异形窗体-从入门到精通从入门到精通
从Windows操作系统诞生的第一天开始,所有的窗口都是矩形的。但是,打破这一戒规标新出异的软件正越
来越多,即使是Microsoft这个矩形窗体的鼻祖,也开始使用不规则的异形窗体,Windows Media Player就是一个
例子。可惜的是,构造异形窗体向来不是一件轻松的事情,不过现在不同了!有了.NET框架特别是Windows
Forms包,即使构造复杂的窗体形状也变得轻而易举。
既然已经提到Media Player,那就继续用它作为例子说明吧。Media Player运用了许多特殊的技术,足以作
为典型的范例。想必大家的Windows系统上都安装了Media Player,你可以按照本文的说明马上打开试试。
本文将示范异形窗体的构造过程,这个异形窗体拥有与Meida Player相似的外形。但在说明这一复杂异形窗
体的构造过程之前,首先我们要了解一些基础知识。
一、异形窗体基础一、异形窗体基础
构造异形窗体的基本思路很简单,只需定义向量形式的窗体轮廓,然后把这个窗体轮廓指定给窗体。
窗体的外形由.NET框架类Region定义。每一个Windows的Form有一个成员对象Region,但在默认情况
下,Form不会带有用户自定义的Region,其对象引用是null(C#)或Nothing(VB.NET),窗体显示为矩形
(Windows XP的“主题”功能会修改窗体的外观,不过本文将忽略这一细节)。
创建一个Region类的实例,填充异形窗体的形状信息,就可以修改窗体的外形。要做到这一点,最简单的办
法是使用GraphicsPath对象。GraphicsPath是一个GDI+类,属于System.Drawing.Drawing2D名称空间。
GraphicsPath类能够以向量的形式描述形状,用法很简单,只需给出窗体的轮廓定义即可。定义好的向量路径提
交给Region对象的构造函数,Region对象自动把路径信息转换成形状定义数据。窗体获得形状数据之后,它的形
状就随之改变。
因此,要简单地改动一下窗体外形简直轻而易举。.NET的GraphicsPath类功能相当强大,部分方法可以说很
复杂。不过,本文只需用到直线和弧形组合成的简单路径。
二、构造椭圆窗体二、构造椭圆窗体
下面先来看一个椭圆窗体的简单例子。首先创建一个VS.NET Windows窗体工程,VS.NET将创建一个默认
的矩形窗体。椭圆窗体轮廓的图形路径很简单,只需调用一下GraphicsPath对象的AddEllipse()方法即可得到。
GraphicsPath提供了许多方法来构造复杂的向量路径,部分将在本文后面的例子用到,但现在我们只需要一个椭
圆。下面这段代码显示了如何创建路径并加入一个椭圆:
Imports System.Drawing.Drawing2D
Dim oPath As New GraphicsPath()
oPath.AddEllipse(0, 0, 200, 100)
这段代码定义的椭圆开始位置是(0,0),也就是窗体(即绘图平面)的左上角,椭圆的大小是200 X
100。注意,为了让这段代码顺利通过编译,必须导入System.Drawing.Drawing2D名称空间。所有的Windows窗
体应用自动引用该名称空间,所以不必为它添加工程引用。
AddEllipse()方法有几种重载的形态,其中一种允许传入一个Rectangle对象替代矩形的坐标。如果椭圆的矩
形大小和窗体大小一样,用这个方法就很方便,因为每一个Windows的窗体都有一个ClientRectangle成员:
Dim oPath As New GraphicsPath()
oPath.AddEllipse(Me.ClientRectangle)
利用这个路径创建Region对象,然后再传递给窗体。下面是窗体的Load事件句柄:
Private Sub Form1_Load( ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Dim oPath As New GraphicsPath()
oPath.AddEllipse(Me.ClientRectangle)
Me.Region = New Region(oPath)
End Sub
![](https://csdnimg.cn/release/download_crawler_static/15051435/bg2.jpg)
对于C#,处理方法也和VB.NET相似。下面是生成椭圆窗体的C#代码:
private void Form1_Load(object sender, System.EventArgs e)
{
GraphicsPath oPath = new GraphicsPath();
oPath.AddEllipse(this.ClientRectangle);
this.Region = new Region(oPath);
}
图一:椭圆窗体
鉴于C#和VB.NET在构造异形窗体方面的差别实在不大,下面的例子将只介绍VB.NET,想必C#开发者也一
样能够通过VB.NET版的例子掌握异形窗体设计思路。
现在可以运行这个VB.NET应用了,图一就是运行结果(加上了一个“关闭”按钮)。大家一眼就可以看出,这
个窗口看起来有点古怪,就象其他Windows窗体一样,它也有一个标题,但椭圆切割了窗体标题,看起来特别不
专业。
图二:设计时异形窗体仍旧显示为矩形
另一个马上会注意到的细节是在设计模式下,窗体仍旧显示为矩形(图二)。这很正常,只是稍微增加了在
异形窗体中放置控件的难度,但除此之外,异形窗体的设计和编程完全与普通窗体一样,包括改变大小、拖放控
件、设计事件句柄等。
首先来解决窗口标题条的问题。一般地,大多数异形窗体不会使用操作系统默认加上的标题条,部分异形窗
体会另外制作一个精致的标题条,通常由图形专家设计,以图形的形式放入窗体。有些应用能够以多种不同的模
式运行,当它以异形窗体模式运行时,标题条隐藏,只有以普通窗体模式运行时,标题条才会显示出来。
Windows Media Player就是一个很典型的例子,参见图三和图四。
![](https://csdnimg.cn/release/download_crawler_static/15051435/bg3.jpg)
图三:以异形窗体模式运行的Media Player
图四:以标准窗体模式运行的Media Player
从图三和图四可以看出,异形窗体是从矩形窗体标题条下面“切割”出一部分来。对于前面例子中的椭圆窗
体,我们也可以按照同样的方式处理。下面的代码片断针对窗体标题条和窗体边框作了调整:
' 计算椭圆的大小
Dim iElTop, iElLeft, iElHeight, iElWidth As Integer
iElTop = SystemInformation.BorderSize.Height + _
SystemInformation.CaptionHeight + 2
iElLeft = SystemInformation.BorderSize.Width + 2
iElHeight = Height - iElTop - SystemInformation.BorderSize.Height - 3
iElWidth = Me.Width - iElLeft - SystemInformation.BorderSize.Width - 3
' 创建图形路径并设置其大小
oPath = New GraphicsPath()
oPath.AddEllipse(iElLeft, iElTop, iElWidth, iElHeight)
这段代码看起来要比实际情形复杂一些,大多数代码都在和SystemInformation类(及其静态方法)打交道,
查询标题条高度之类的信息。
![](https://csdnimg.cn/release/download_crawler_static/15051435/bg4.jpg)
再次运行这个VB.NET工程,可以看到它仍是一个椭圆,但要比以前的小一点,看起来舒服不少——虽然还
不够完美,但至少改进了不少,标题条已经消失不见了。不过现在出现了另一个问题,在Windows中移动窗口最
方便的办法就是点住标题条拖动,现在没有了标题条,要移动窗口就很困难了。
三、实现拖动功能三、实现拖动功能
大多数异形窗体采用同样的办法解决窗体移动问题:允许用户点击窗体背景的任意位置移动窗体。Listing 1
的代码给出了具体实现。这段代码对于任何异形窗体来说都很有用,所以作为一个新的窗体类ShapedForm实
现,本文其余的窗体都将从这个窗体派生。
Listing 1:ShapedForm类实现所有异形窗体必需的标准功能
Imports System.Drawing.Drawing2D
Public Class ShapedForm
Inherits System.Windows.Forms.Form
' 可以在子类窗体Load事件之前赋值
Public oFormPath As GraphicsPath
Private oOriginalRegion As Region = Nothing
' 用于窗体移动
Private bFormDragging As Boolean = False
Private oPointClicked As Point
#Region " Windows 窗体设计器生成的代码"
' 此处略...
Private Sub ShapedForm_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' 给子类提供一个设置窗体形状的机会
Me.SetInitialFormShape()
If Not Me.oFormPath Is Nothing Then
Me.AssignShapePath()
End If
End Sub
Public Sub AssignShapePath()
If Me.oOriginalRegion Is Nothing Then
Me.oOriginalRegion = Me.Region
End If
Me.Region = New Region(Me.oFormPath)
Me.Invalidate()
End Sub
Public Sub ResetShape()
Me.Region = Me.oOriginalRegion
Me.Invalidate()
End Sub
Public Overridable Sub SetInitialFormShape()
' 这个方法用来让子类覆盖
End Sub
Private Sub ShapedForm_MouseDown( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles MyBase.MouseDown
Me.bFormDragging = True
Me.oPointClicked = New Point(e.X, e.Y)
End Sub
Private Sub ShapedForm_MouseUp( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles MyBase.MouseUp
Me.bFormDragging = False
End Sub
Private Sub ShapedForm_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles MyBase.MouseMove
If Me.bFormDragging Then
Dim oMoveToPoint As Point
' 以当前鼠标位置为基础,找出目标位置
oMoveToPoint = Me.PointToScreen(New Point(e.X, e.Y))
' 根据开始位置作出调整
oMoveToPoint.Offset(Me.oPointClicked.X * -1, _
(Me.oPointClicked.Y + _
SystemInformation.CaptionHeight + _
SystemInformation.BorderSize.Height) * -1)
' 移动窗体
Me.Location = oMoveToPoint
End If
End Sub
End Class
剩余21页未读,继续阅读
资源评论
![avatar-default](https://csdnimg.cn/release/downloadcmsfe/public/img/lazyLogo2.1882d7f4.png)
![avatar](https://profile-avatar.csdnimg.cn/default.jpg!1)
weixin_38741195
- 粉丝: 2
- 资源: 970
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![voice](https://csdnimg.cn/release/downloadcmsfe/public/img/voice.245cc511.png)
![center-task](https://csdnimg.cn/release/downloadcmsfe/public/img/center-task.c2eda91a.png)
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![dialog-icon](https://csdnimg.cn/release/downloadcmsfe/public/img/green-success.6a4acb44.png)