回 帖 发 新 帖 刷新版面

主题:含笑不语:异型窗体代码逐句详解,请高手指教点评,菜鸟分享

在自学VB过程中,我遇到许多困难,很多教材语焉不详,让身为菜鸟的我吃够了苦头!特发此帖,作为我的VB自学系列笔记之一,希望能给广大VB菜鸟同仁带来帮助!
                                        ------------------含笑不语 2008-1-6
                   特别鸣谢  btxdlibin大大  tanchuhan大大  merry05大大  

            实例1   异型窗体

1.建Form1,添加2个CommandButton,Caption1="外边为圆角矩形,里边为椭圆透明洞的窗体" Caption2="中间有椭圆透明洞的窗体"
  添加From2, Caption="中间有椭圆透明洞的窗体" , BackColor=&H00FFFF80&

2.Form1代码:

Option Explicit  '(注释1)
    Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long  '(注释2) 用API函数 CreateRectRgn 创建剪裁区域,用来在上边建立各种异型窗体
    Private Declare 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'(注释3)用API函数 CreateRoundRectRgn创建外边的圆 角矩形
    Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long '(注释4) 用API函数 CreateEllipticRgn 创建里边的椭圆
    Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long'(注释5) 用API函数 CombineRgn 将两个区域组合在一起
    Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As long) As Long'(注释6) 用API函数 SetWindowRgn 将组合在一起的区域创建为新区域
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long'(注释7) 删除创建的新区域
    Private Const RGN_DIFF = 4'(注释8)用Const将RGN_DIFF声明为常数4,即将两个区域相减
    Private OutRgn As Long  '声明变量外边圆角矩形OutRgn的数据类型为Long(长整型)
    Private InRgn  As Long  '声明变量里边椭圆InRgn的数据类型为Long(长整型)
    Private MyRgn As Long   '声明变量创建的新区域MyRgn的数据类型为Long(长整型)

Private Sub Command1_Click()
     If OutRgn <> 0 And InRgn <> 0 And MyRgn <> 0 Then Exit Sub     '  (注释9)防止重复创建图形
     Dim w As Long, h As Long      '声明变量w,h的数据类型为Long(长整型)
     w = ScaleX(Form1.Width, vbTwips, vbPixels)    '  (注释10)  将Form1的窗体宽度由缇变为像素值后赋给变量W
     h = ScaleY(Form1.Height, vbTwips, vbPixels)    '将Form1的窗体高度由缇变为像素值后赋给变量h
     MyRgn = CreateRectRgn(0, 0, 0, 0)    '用API函数 CreateRectRgn 创建剪裁区域MyRgn
     OutRgn = CreateRoundRectRgn(30, 30, w - 30, h - 30, 100, 100)     '用API函数 CreateRoundRectRgn 创建圆角矩形OutRgn
     InRgn = CreateEllipticRgn(100, 100, w - 100, h - 100)     '用API函数 CreateEllipticRgn 创建椭圆InRgn
     Call CombineRgn(MyRgn, OutRgn, InRgn, RGN_DIFF)     '(注释11)将圆角矩形区域OutRgn中不属于椭圆InRgn的区域合并到MyRgn
     Call SetWindowRgn(Form1.hWnd, MyRgn, True)     '在Form1中以MyRgn为句柄创建新区域
     Form1.BackColor = QBColor(4)     '(注释12)将Form1的背景色设置为红色
End Sub

Private Sub Command2_Click()
     Form2.Show     '显示Form2
End Sub

Private Sub Form_Load()
     OutRgn = 0    '加载窗体Form1时将区域OutRgn设置为0
     InRgn = 0    '加载窗体Form1时将区域InRgn设置为0
     MyRgn = 0    '加载窗体Form1时将区域MyRgn 设置为0
End Sub

Private Sub Form_Unload(Cancel As Integer)
     If MyRgn <> 0 Then DeleteObject MyRgn   '卸载窗体Form1时如果区域MyRgn不为0则删除MyRgn
     If OutRgn <> 0 Then DeleteObject OutRgn   '卸载窗体Form1时如果区域OutRgn不为0则删除OutRgn
     If InRgn <> 0 Then DeleteObject InRgn   '卸载窗体Form1时如果区域InRgn不为0则删除InRgn
End Sub
   




Form2代码:

Option Explicit'(注释1)
    Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long'(注释2) 用API函数 CreateRectRgn 创建剪裁区域,用来在上边建立各种异型窗体
    Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long,ByVal Y2 As Long) As Long'(注释4) 用API函数 CreateEllipticRgn 创建里边的椭圆
    Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long'(注释5) 用API函数 CombineRgn 将两个区域组合在一起
    Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Long) As Long'(注释6) 用API函数 SetWindowRgn 将组合在一起的区域创建为新区域

Private Sub Form_Resize()    '(注释13)用Form_Resize()事件设置控件的属性
     Const RGN_DIFF = 4    '(注释8)用Const将RGN_DIFF声明为常数4,即将两个区域相减 
     Dim outer_rgn As Long     '声明变量outer_rgn为Long型(长整型)
     Dim inner_rgn As Long    '声明变量inner_rgn为Long型(长整型)
     Dim combined_rgn As Long    '声明变量combined_rgn为Long型(长整型)
     Dim wid As Single        '声明变量wid为Single型(单精度浮点数)
     Dim hgt As Single        '声明变量hgt为Single型(单精度浮点数)
     Dim border_width As Single     '声明变量border_width为Single型(单精度浮点数)
     Dim title_height As Single     '声明变量title_height为Single型(单精度浮点数)
     If WindowState = vbMinimized Then Exit Sub      '(注释14)如果窗口最小化那么就退出.(窗口最小化的话,就没有坐标来创建图形了)
     Me.ScaleMode = 3      '将Form2的ScaleMode属性设置为3,否则的话,Form2有可能编译通不过!
     wid = ScaleX(Width, vbTwips, vbPixels)      '  (注释10)  将Form2的窗体宽度由缇变为像素值后赋给变量wid
     hgt = ScaleY(Height, vbTwips, vbPixels)     '  (注释10)  将Form2的窗体高度由缇变为像素值后赋给变量 hgt
     outer_rgn = CreateRectRgn(0, 0, wid, hgt)     '(注释2) 用API函数 CreateRectRgn 创建外边的矩形窗体
     border_width = (wid - ScaleWidth) / 2      '(注释15)计算窗体Form2边框宽度
     title_height = hgt - border_width - ScaleHeight      '(注释16)计算窗体Form2标题栏高度
     inner_rgn = CreateEllipticRgn(border_width + ScaleWidth * 0.1, title_height + ScaleHeight * 0.1, ScaleWidth *       0.9, ScaleHeight * 0.9)     '(注释17) 用 API函数 CreateEllipticRgn 创建里边的椭圆
     combined_rgn = CreateRectRgn(0, 0, 0, 0)     '(注释2) 用API函数 CreateRectRgn 创建剪裁区域,用来在上边建立各种异型窗体
     CombineRgn combined_rgn, outer_rgn,inner_rgn, RGN_DIFF     '(注释11)将矩形区域outer_rgn中不属于椭圆inner_rgn的区域合并到combined_rgn中
     SetWindowRgn hWnd, combined_rgn, True        '在Form2中以combined_rgn为句柄创建新区域
End Sub

回复列表 (共37个回复)

21 楼

注释16:   title_height = hgt - border_width - ScaleHeight
 
    hgt---------------------------------Form2的窗体高度
    border_width------------------------Form2窗体的边框宽度
    ScaleHeight-------------------------Form2的实际工作区高度,即除去边框和标题栏的高度
    title_height------------------------Form2窗体标题栏高度


注释17:   inner_rgn = CreateEllipticRgn(border_width + ScaleWidth * 0.1, title_height + ScaleHeight * 0.1, ScaleWidth * 0.9, ScaleHeight * 0.9)     

    border_width------------------------Form2窗体的边框宽度
    ScaleWidth * 0.1--------------------Form2窗体的实际工作区(即除去边框)宽度的0.1倍
    title_height------------------------Form2窗体标题栏高度
    ScaleHeight * 0.1-------------------Form2窗体的实际工作区(即除去边框)高度的0.1倍
    ScaleWidth * 0.9--------------------Form2窗体的实际工作区(即除去边框)宽度的0.9倍
    ScaleHeight * 0.9-------------------Form2窗体的实际工作区(即除去边框)高度的0.9倍
补充:
    CreateEllipticRgn是以四个坐标位置来创建个椭圆区域,inner_rgn表示这个区域的地址long
    outer_rgn,inner_rgn,combined_rgn 这几个是表示区域,储存区域的位置用Long表示.
    wid,hgt等这几个是表示长度单位,数据有小数部分,为了数据的准确性声明成单精度single.




22 楼

代码消化了,后面应该自己发挥应用.
创建不规则图形在界面设计方面是很有用的.
继续努力!


23 楼

就是不知道我的理解对不对?

24 楼

谢谢  btxdlibin大大  的鼓励!

25 楼

写这个东东不容易啊,要花费很多心血的,顶一下!

26 楼

不容易呀!!!
帅哥有耐心,也有恒心;我喜欢,我支持!

27 楼

顶了,谢谢大哥!
收藏了,
以后慢慢消化!

28 楼

写了这么多,怎么也的支持

内容不错

29 楼

写这个东东不容易啊,要花费很多心血的,顶一下!

不容易呀!!!
帅哥有耐心,也有恒心;我喜欢,我支持!
-----------------------------------------
    这一篇帖子,我花了好几个月的工夫才完成的!看到上述评价我都想掉泪了,没啥说的 ,就一句话--知音.我以后还会发类似的帖子的!不为别的,只为别人不再象我这样在自学VB的时候受这么多罪!

30 楼

学了大半年,没多大进展,也是因书出得不全.入门书倒买了N本,白花钱不说.还倒贴上人生岁月,唉.

我来回复

您尚未登录,请登录后再回复。点此登录或注册