用VB实现不规则窗体(上)

  让自己设计的软件有一个不规则的窗体似乎有点“歪门邪道”,但不知你见没见过Norton Utilities 3.0 for Win95中的主界面——一个极为精致的小方盒,还有附带的Norton CrashGuard 3.0的盾牌界面,如果你见过,那么相信无论上述两个软件质量如何,你也一定会被这些精巧绝伦的“异形”窗口所吸引住的。事实上,NU 3.0的应用曾让笔者的系统全面崩溃,但笔者仍然十分欣赏它的界面。

  这种不规则界面是可以用VB实现的。其关键是调用API函数Set WindowsRgn()。首先,新建一窗体Form1,为了不使您选中的范围跑到窗体之外,将它的Windows State属性设为I-Maximize,为了使出现的不规则窗体较为醒目和对选择区域的相对位置有所了解,将窗体选一种比较鲜艳的颜色,例如红色,并在窗体上随便放几个控件作为参照物。

  一、矩形窗体

  这里的矩形窗体可不是普通的矩形窗体,而是将正常窗体中任意选中的矩形区域作为窗体,当然也可以没有边框和标题栏。新建一模块,在模块中声明API函数SetWindowsRgn()和CreateRect Rgn():

  Declare Function SetWindow Rgn Lib“user32”(ByVal hWnd As Long,ByVal hRgn As Long,ByVal bRedraw As Boolean)As long Declare Function createRect Rgn Lig“gdi32"(ByVal X1 As Long,ByVal Y1 As Long,ByVal X2 As Long,ByVal Y2 As long)As long()

  建议用API文本查看器粘贴,然后编写Form-load()事件:

  Private Sub Form-load()

  SetWindowsRgn hwnd,CreateRectRgn(50,100,500,300)True

  End Sub

  运行即可看到出现了一矩形窗体。显然CreateRect Rgn()函数声明中的X1、Y1、X2、Y2参数决定了选择区域的位置及大小。注意,如果就这样生成·EXE文件,它是不能正常关闭的,因为它没有“关闭”按钮。所以应该在运行时的可视区域中添加一按钮,在它的click()事件中写入END即能使程序能正常退出。以下各例亦同此要求。

  二、带圆角的矩形窗体

  在上例的模块中添加声明API函数Create Round RectRgn():

  Delare Function CreateRoundRectRgn Lib“gdi32”(ByVal X1 As Long,ByVal Y1 As Long,ByVal X2 As Long,ByVal Y2 As Long,ByVal X3 As Long,ByVal Y3 As Long)As Long

  在声明中,X1、Y1、X2、Y2意义同函数CreateRectRgn()是一样的,而X3、Y3两个参数代表了横向、纵向拐角处的曲率半径。将上例的Form_lod()事件改写为:

  Private Sub Form_load()

  SetWindowRgn hWnd,CreateRoundRectRgn(50,100,500,300,150,100),True

  End Sub

  运行即可看出在矩形的四个角处已经呈现圆弧状了。

  三、椭圆窗体

  在上例的模块中再添加声明API函数CreateEllipticRgn():

  Declare function CreateEllipticRgn Lib“gdi31”(ByVal X1 As Long,ByVal Y1 As Long,ByVal X2 As Long,ByVal Y2 As Long)As Long

  各参数不用多说,现举一例如下:

  Private Sub Form-load()

  SetWindowRgn hwnd,CreateEllipticRgn(50,100,500,300),True

  End Sub

  四、任意形状的窗体

  这是最高境界了,当然也比较麻烦。在上例的模块中再添加声明API函数CreatePolygonRgn():

  Declare Function CreatePolygonRgn Lib“gdi32”(lpPoint As POINTAPI,ByVal nCount As Long,ByVal nPolyFill Mode As Long)As Long

  该函数有3个参数,其中lpPoint决定了窗体的形状,它是一个POINTAPI类型的变量。在此模块的最前面进行如下的类型声明:Type POINTAPI

  X AS long

  Y As long

  End Type

  您也许感到奇怪,两个(X和Y)long型的存储空间就可以储存任意复杂的窗体开头信息吗?当然不是,Create PolygonRgn()函数在使用lpPoint参数的时候,lpPoint相当于一个指针,指向一个连续存储空间的第一个值。