VPS    微软    Win10    苹果    Office2016

VB创建不规则窗体经验总汇

 编程开发   2005-02-04

很多人都很热衷于创建形状奇怪的窗体。而且不断的有热心的家伙们将他们的发现放到我们这里与大家分享。今天我将我所知道的方法总结一下。希望对大家有所帮助。
    一般来说,要创建一个不规则的窗体。我们需要使用一个Win32 API: SetwindowRgn。这个API您可以在Api浏览器中找到。这个Api的作用就是将窗体的“剪”成一个指定的形状。下面是这个Api声明于解释:
    Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long,ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
    它有三个参数。
    第一个(hWnd)是用来指定被剪切的对象的句柄,比如Picture图形框等, 我们一般就是用窗体的hWnd属性;
    第二个(hRgb)指明剪切的形状, 即指定的几何图形特征, 此参数也必须由相应的API 函数提供说明。用那些APi可以创建一个您想要的区域(窗体的形状)。然后这些Api会返回一个数值。这个数值就是这个形状在Windows中的句柄(可以理解为身份证号码)。SetWindowsRgn可以通过这个数值来找到我们创建的那个区域;
    第三个(bRedraw)是一个布尔变量, 一般可设置为真(True)。

    看来仅仅有SetWindowsRgn还不行。我们还必须创建一个区域。创建区域可以使用如下的一些Api:
    CreateRectRgn :  建立矩形区域,其参数分别为矩形的左上角坐标及右下角坐标。但是由于窗体默认就是一个矩形,所我们应该用不到它;

    CreateRoundRectRgn:建立圆角矩形区域,其参数分别为左上角及右下角坐标, 还有圆角直径等, 当圆角直径接近或超过矩形的长度时, 将呈现为圆或椭圆形;

    CreateEllipticRgn :建立椭圆矩形区域,参数分别椭圆的约束矩形左上角与左下角顶点的坐标;;

    所以现在我们就可以创建一下形状比较简单的窗体了。比如下面的代码我们就创建了一个椭圆形的窗体:

    Option Explicit
    'Win32 Api 的声名
    Private Declare Function CreateEllipticRgn Lib "gdi32" Alias "CreateEllipticRgn" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long,ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

    Private Sub Form_Load()
Dim Result As Long '声明变量用于保存“区域”的句柄
Me.Show
Result = CreateEllipticRgn(0, 0, 300, 200) '创建“区域”并将其句柄保存到变量中
SetWindowRgn Me.Hwnd, Result, True '根据前面创建的区域对窗体进行“剪裁”
    End Sub

    但是你要说,我想创建的窗体是一个人的形状或者是其他的不规则的形状呀!是的,上面的方法只能创建一些简单的几何图形。创建比较复杂形状的窗体我们仍然需要使用SetWindowRgb这个Api来对窗体进行“剪裁”。但是我们需要用其它的Api来创建复杂的“区域”。一般的,我们会用到下面的Api。这些Api配合使用就会得到复杂形状的区域。从而我们可以使用SetWindowRgb裁出窗体。

    CreatePolygonRgn : 用于通过连接各个点来创建一个区域

    CombineRgn:        用于对两个区域进行运算。比如合并两个区域或这是将两个区域相减、求交集等等。

    下面我们来详细的介绍一下这两个Api:
    CreatePolygonRgb

    Declare Function CreatePolygonRgn Lib "gdi32" Alias "CreatePolygonRgn" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long

   参数一(lpPoint): POINTAPI类型的变量。POINTAPI是一个用于描述点坐标的结构。他有两个成员x与y。您可以在Api浏览器中找到它。在这里我们需要一个数组,并将这个属组的第一个元素作为这里的参数。
   参数二(nCount):  区域顶点的个数。比如一个三角形的区域有三个顶点。我们应该根据这个参数来确定上一个参数使用的数组的大小;
   参数三(nPolyFillMode): 指定区域的填充模式。我们可以使用两个常量作为参数:AlterNATE和WINDING。这两个常量可以在Api浏览器中找到。我们在这里可以直接使用1.

   CombineRgb
   Declare Function CombineRgn Lib "gdi32" Alias "CombineRgn" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long

   参数一(hDestRgn): 目标区域的句柄;
   参数二(hSrcRgn1): 源区域一的句柄;
   参数三(hScrRgn2): 源区域二的句柄。
   参数四(nCombineMode): 合并模式。我们可以在Api浏览器中到这些常量作为它的参数:
          RGN_AND
           Creates the intersection of the two combined regions.
          RGN_COPY
           Creates a copy of the region identified by hrgnSrc1.
          RGN_DIFF
           Combines the parts of hrgnSrc1 that are not part of hrgnSrc2.
          RGN_OR
           Creates the union of two combined regions.
          RGN_XOR
           Creates the union of two combined regions except for any overlapping areas.
    
    好了,下面我们来创建一个沙漏形的区域。

     Option Explicit
    'Win32 API的声明
    Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) 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 SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
    Private Type POINTAPI
        x As Long
        y As Long
     End Type

    Private Sub Form_Load()
    '声明变量
    Dim Result As Long
    Dim Points(5) As POINTAPI

    '更改窗体大小
    With Me
        .Width = 5000
        .Height = 10000
    End With

    '将区域的顶点坐标存入变量
    Points(0).x = 0
    Points(0).y = 0
    Points(1).x = 300
    Points(1).y = 0
    Points(2).x = 175
    Points(2).y = 300
    Points(3).x = 300
    Points(3).y = 600
    Points(4).x = 0
    Points(4).y = 600
    Points(5).x = 125
    Points(5).y = 300

    '创建区域
    Result = CreatePolygonRgn(Points(0), 6, 1)

    '“裁剪”窗体
    SetWindowRgn Me.hwnd, Result, True

    End Sub

    另外,我们还应该注意一个Win32 Api:DeleteObject。 我们用Api创建了一个区域。虽然不可见,但是它却是一个对象。如果我们不将其删除,它就会存在于系统中消耗系统资源,所以我们不用的时候就应该将它删除掉。这个Api只有一个参数就是指定要删除对象的句柄。

  • VB,话说我这次的VB二级考试没通过,真郁闷,对文科生,尤其是不怎么爱数字的文科男生真是一种折磨啊[Yoci-06]

    7 10
     
  • 想想N年前,本人应聘时面试就是vb,如今啊。。。

    10 10
     
  • 7 10
     
  • 说得很好,受益匪浅啊~~~

    7 10
     
  • 在学VB,先看看

    8 10
     
  • 有代码下载才在硬道理。

    6 10
     





评论内容 (*必填):
Ctrl + Enter 快速提交