VB.Net创建不规则窗体

 
VB.Net创建不规则窗体   
 
一般说来,应用程序的窗体都是规则的,即是矩形窗体。有时候为了某种特殊的用途,我们希望改变应用程序窗体的形状,比如做个个性十足的 mp3 播放器,小时钟等等,这就需要 " 定制 " 我们的应用程序。另外,特殊形状的窗体有时候也能吸引用户的注意力,使得他们格外注意你的程序。

VB6 里面,我们一般通过以下代码来创建不规则窗体。
Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, _ ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, _ ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Sub Form_Activate()
Dim hndRgn As Long
hndRgn = CreateEllipticRgn(0, 0, 175, 175)
Call SetWindowRgn(Me.hWnd, hndRgn, True)
Call DeleteObject(hndRgn)
End Sub
首先用 Win32 API CreateEllipticRgn 创建一个圆形的区域,然后设置 Form 的区域为用户自定义的 Region ,这样我们就可以得到下面一个圆形的窗体
为了更美观一点,我们可以设 Form BorderStyle None ,然后自己画一个 TitileBar ,就可以做成比较活泼的应用程序。

VB.Net
里面如何实现以上效果:
VB.NET
是一中跨平台的语言,更好的利用了面向对象机制。它的面向对象能力扩展了语言本身的通路:一切都是对象。这意味着比在以前的 VB 版本里,你获得了更多的内在功能,你将很少被迫使用 Windows API 。因此在 VB.Net 里面我们也只好放弃 VB6 里面利用 API 的观念,用 VB.Net 强大的对象机制来阐述以上话题。
VB.Net 里面, Form 有一个 Reigin 属性,我们通过创建自定义的 Reigin ,然后指定 Form Reigin ,就可以得到不规则的窗体。而且 VB.Net 里面的 Reigin 对象功能强大,远超过了之前 VB 的限制,因此我们可以作出很多漂亮的界面。

Regin
对象
System.Drawing
的一个对象,指示由矩形和由路径构成的图形形状的内部。因为区域的坐标是在全局坐标中指定的,所以可对它进行缩放。然而,在绘制表面上,它的内部取决于表示它的像素的大小和形状。应用程序可以使用若干区域来堆砌绘图操作的输出。窗口管理器则使用区域来定义窗口的绘制区域。这些区域被称为剪辑区域。应用程序还可以在命中检测的操作中使用区域,例如检查一个点或矩形是否与某个区域相交。应用程序可通过使用 Brush 对象来填充一个区域。
GraphicsPath
表示一系列相互连接的直线和曲线,应用程序使用路径来绘制形状的轮廓、填充形状内部和创建剪辑区域。图形引擎在全局坐标空间中维护路径内的几何形状的坐标。路径可由任意数目的图形(子路径)组成。每一图形都是由一系列相互连接的直线和曲线或几何形状基元构成的。图形的起始点是相互连接的一系列直线和曲线中的第一点。终结点是该序列中的最后一点。几何形状基元的起始点和终结点都是由基元规范定义的。
下面我们看两个具体的实例
1.
文字格式的窗体
Form Load 事件加入以下代码:
Dim text_path As GraphicsPath
Dim text_region As Region
Me.BackColor = Color.Red
Me.Width = 600
' Create the text path.
text_path = New GraphicsPath( Drawing.Drawing2D.FillMode.Alternate)
text_path.AddString("CSDN", New FontFamily("Times New Roman"), FontStyle.Bold, 200,New Point(10, 10),
StringFormat.GenericDefault)
' Create a Region from the path.
text_region = New Region(text_path)
' Constrain the form to the region.
Me.Region = text_region
运行将将得到如下形状的窗体,记住按 Shift F5 中止程序。

2.
椭圆形状的窗体:
同样加入以下代码,得到如下窗体
Me.Width = 300
Me.Height = 220
Me.BackColor = Color.RoyalBlue
Dim m_path As GraphicsPath
m_path = New GraphicsPath(FillMode.Winding)
m_path.AddEllipse(1, 1, 200, 200)
Dim m_region As New Region(m_path)
Me.Region = m_region
以上只是两个简单的例子,通过利用 Region GraphicsPath 对象,你将得到更多有趣的效果。
 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于使用了一些新的函数,本程序必须在Windows2000下运行。 Option Explicit Public Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long Public Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long Public Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long Public Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long Public Const RGN_OR = 2 Public Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Public Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Public Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End Type Public Const BITMAP_SIZE = 24 '=Len(BITMAP) Dim bmByte() As Byte Public Declare Function ReleaseCapture Lib "user32" () As Long Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Public Const HTCAPTION = 2 Public Const WM_NCLBUTTONDOWN = &HA1; Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long Public Const WS_EX_LAYERED = &H80000; Public Const GWL_EXSTYLE = (-20) Public Const LWA_ALPHA = &H2; Public Const LWA_COLORKEY = &H1; Public Sub SetAutoRgn(hForm As Form, Optional transColor As Byte = vbNull) Dim X As Long, Y As Long Dim Rgn1 As Long, Rgn2 As Long Dim SPos As Long, EPos As Long Dim bm As BITMAP Dim hbm As Long Dim Wid As Long, Hgt As Long Dim xoff As Long, yoff As Long '获取窗体背景图片尺寸 hbm = hForm.Picture GetObjectAPI hbm, Len(bm), bm Wid = bm.bmWidth Hgt = bm.bmHeight With hForm .ScaleMode = vbPixels xoff = (.ScaleX(.Width, vbTwips, vbPixels) - .ScaleWidth) / 2 yoff = .ScaleY(.Height, vbTwips, vbPixels) - .ScaleHeight - xoff '改变窗体尺寸 .Width = (Wid + xoff * 2) * Screen.TwipsPerPixelX .Height = (Hgt + xoff + yoff) * Screen.TwipsPerPixelY End With ReDim bmByte(1 To Wid, 1 To Hgt) GetBitmapBits hbm, Wid * Hgt, bmByte(1, 1) '获取图像数组 '如果没有传入transColor参数,则用第一个像素作为透明色 If transColor = vbNull Then transColor = bmByte(1, 1) Rgn1 = CreateRectRgn(0, 0, 0, 0) For Y = 1 To Hgt '逐行扫描 X = 0 Do X = X + 1 While (bmByte(X, Y) = transColor) And (X < Wid) X = X + 1 '跳过是透明色的点 Wend SPos = X While (bmByte(X, Y) <> transColor) And (X < Wid) X = X + 1 '跳过不是透明色的点 Wend EPos = X - 1 '这一段是合并区域 If SPos <= EPos Then Rgn2 = CreateRectRgn(SPos - 1 + xoff, Y - 1 + yoff, EPos + xoff, Y + yoff) CombineRgn Rgn1, Rgn1, Rgn2, RGN_OR DeleteObject Rgn2 End If Loop Until X >= Wid Next Y SetWindowRgn hForm.hwnd, Rgn1, True '设定窗体形状区域 DeleteObject Rgn1 End Sub Option Explicit Private Sub Form_DblClick() Unload Me End Sub Private Sub Form_Load() 'Me.Show Dim t As Single Dim rtn As Long rtn = GetWindowLong(hwnd, GWL_EXSTYLE) rtn = rtn Or WS_EX_LAYERED SetWindowLong hwnd, GWL_EXSTYLE, rtn SetLayeredWindowAttributes hwnd, 0, 192, LWA_ALPHA '半透明 'SetLayeredWindowAttributes hwnd, &H0;, 0, LWA_COLORKEY '去除透明色 t = Timer If Me.Picture <> 0 Then Call SetAutoRgn(Me) ', 0) End If 'MsgBox "运行时间:" & Timer - t & "秒", vbInformation End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = vbLeftButton Then ReleaseCapture SendMessage Me.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0& End If End Sub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值