zoukankan      html  css  js  c++  java
  • 《在VB中创建独立控制界面的 ActiveX Dll 部件》2000/02/01 的老帖找到还真不容易!

     由 Microsoft 所提出的部件对象模型 (COM) ,包括 Automation 和 ActiveX 规范。通过 ActiveX
    部件技术可以把已创建的基于对象的部件组合起来,这些部件可以通过许多不同的工具来创建。应用"部
    件软件开发"方法有代码重用、模块功能分明等许多好处。下面以创建独立的界面控制 ActiveX Dll 部
    件为题,做进一步分析:

        以下两个 ActiveX Dll 部件均实现了"在部件内部响应事件",即:在类模块内引用带事件的对象,以
    及在程序运行阶段动态添加控件(实现的技术细节可参阅《MSDN》)。
    例2:在 Delphi 提供了 Splitter 控件,轻而易举就实现了窗体界面的分割视图,而在 VB 中要实现这一
        功能则要编写大量代码。
        可参阅 VB 6 的"树状视图列表视图拆分条"控件集或"VB 应用程序向导 --> 资源管理器样式"代码,
        现将其加工移植为 ActiveX Dll 部件:
            创建ActiveX Dll(命名为:EasyViews)工程,并在类模块(命名为:SplitView)
            添加如下代码:

    Option Explicit
    Dim mbMoving As Boolean

    Const iError = 120
    Const iErrorXY = 150
    Const SplitterHW = 80

    Dim LeftCtl As Control
    Dim RightCtl As Control
    Dim TopCtl As Control
    Dim BottomCtl As Control

    Dim WithEvents ImgSplitterH As Image
    Dim WithEvents ImgSplitterV As Image

    Dim PictureH As PictureBox
    Dim PictureV As PictureBox

    Dim WithEvents FormX As Form

    Dim iMinWidth As Integer
    Dim iMinHeight As Integer
    Dim iLeftMargin As Integer
    Dim iRightMargin As Integer
    Dim iTopMargin As Integer
    Dim iBottomMargin As Integer

    Public Property Get LeftMargin() As Integer
           LeftMargin = iLeftMargin
    End Property

    Public Property Let LeftMargin(ByVal vNewValue As Integer)
           iLeftMargin = vNewValue
    End Property

    Public Property Get RightMargin() As Integer
           RightMargin = iRightMargin
    End Property

    Public Property Let RightMargin(ByVal vNewValue As Integer)
           iRightMargin = vNewValue
    End Property

    Public Property Get TopMargin() As Integer
           TopMargin = iTopMargin
    End Property

    Public Property Let TopMargin(ByVal vNewValue As Integer)
           iTopMargin = vNewValue
    End Property

    Public Property Get BottomMargin() As Integer
           BottomMargin = iBottomMargin
    End Property
    Public Property Let BottomMargin(ByVal vNewValue As Integer)
           iBottomMargin = vNewValue
    End Property

    Public Property Get MinWidth() As Integer
    MinWidth = iMinWidth
    End Property

    Public Property Let MinWidth(ByVal vNewValue As Integer)
    iMinWidth = vNewValue
    End Property

    Public Property Get MinHeight() As Integer
    MinHeight = iMinHeight
    End Property

    Public Property Let MinHeight(ByVal vNewValue As Integer)
    iMinHeight = vNewValue
    End Property

    Private Sub FormX_Load()
    Dim temp As String

    temp = "DynamicImageH"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.Image", temp, FormX
    On Error GoTo 0
    With FormX.Controls.Item(temp)
         .Visible = True
    End With
    Set ImgSplitterH = FormX.Controls.Item(temp)
    ImgSplitterH.MousePointer = 7 'ccsizeEW

    temp = "DynamicImageV"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.Image", temp, FormX
    On Error GoTo 0
    With FormX.Controls.Item(temp)
         .Visible = True
    End With
    Set ImgSplitterV = FormX.Controls.Item(temp)
    ImgSplitterV.MousePointer = 9 'cc2sizeNS

    temp = "DynamicPictureH"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.PictureBox", temp, FormX
    On Error GoTo 0
    Set PictureH = FormX.Controls.Item(temp)
    PictureH.BorderStyle = 0
    PictureH.BackColor = vbBlack

    temp = "DynamicPictureV"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.PictureBox", temp, FormX
    On Error GoTo 0

    Set PictureV = FormX.Controls.Item(temp)

    PictureV.BorderStyle = 0
    PictureV.BackColor = vbBlack
    LeftCtl.Move LeftMargin, TopMargin
    ImgSplitterV.Move LeftCtl.Left + LeftCtl.Width, LeftCtl.Top, SplitterHW, LeftCtl.Height
    RightCtl.Move ImgSplitterV.Left + SplitterHW, LeftCtl.Top
    RightCtl.Height = LeftCtl.Height
    ImgSplitterH.Move LeftCtl.Left, LeftCtl.Top + LeftCtl.Height, FormX.Width - LeftMargin - RightMargin, SplitterHW
    BottomCtl.Move LeftCtl.Left, LeftCtl.Top + LeftCtl.Height + SplitterHW  'LeftCtl.Height

    Exit Sub
    ErrorHandler:
    temp = temp & "X"
    Resume
    End Sub

    Public Sub Create(LeftCtlX As Object, RightCtlX As Object, BottomCtlX As Object)
    Set LeftCtl = LeftCtlX
    Set RightCtl = RightCtlX
    'Set TopCtl = TopCtlX
    Set BottomCtl = BottomCtlX
    Set FormX = LeftCtlX.Container
    FormX_Load
    End Sub

    Private Sub FormX_Resize()
    If FormX.WindowState <> vbMinimized Then
       If FormX.Width < LeftMargin + RightMargin + SplitterHW + MinWidth + LeftCtl.Width + iErrorXY Then
          FormX.Width = LeftMargin + RightMargin + SplitterHW + MinWidth + LeftCtl.Width + iErrorXY
       End If
       If FormX.Height < TopMargin + BottomMargin + SplitterHW + MinHeight + LeftCtl.Height + iErrorXY + iErrorXY + iErrorXY + 6 Then
          FormX.Height = TopMargin + BottomMargin + SplitterHW + MinHeight + LeftCtl.Height + iErrorXY + iErrorXY + iErrorXY + 6
       End If
       RightCtl.Width = FormX.Width - LeftCtl.Width - SplitterHW - LeftMargin - RightMargin - iErrorXY
       ImgSplitterH.Width = FormX.Width - LeftMargin - RightMargin - iErrorXY
       BottomCtl.Width = ImgSplitterH.Width
       BottomCtl.Height = FormX.Height - ImgSplitterH.Top - BottomMargin - SplitterHW - 405
    End If
    End Sub

    Private Sub ImgSplitterH_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    With ImgSplitterH
         PictureH.Move .Left - 10, .Top, .Width + 30, .Height / 2
    End With
    PictureH.Visible = True
    mbMoving = True
    End Sub

    Private Sub ImgSplitterH_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbLeftButton Then
       If mbMoving Then
          If Y + ImgSplitterH.Top < LeftCtl.Top + MinHeight Then
             PictureH.Top = LeftCtl.Top + MinHeight
          ElseIf Y + ImgSplitterH.Top > FormX.Height - BottomMargin - SplitterHW - MinHeight - iErrorXY - iErrorXY - iErrorXY Then
             PictureH.Top = FormX.Height - BottomMargin - SplitterHW - MinHeight - iErrorXY - iErrorXY - iErrorXY
          Else
             PictureH.Top = Y + ImgSplitterH.Top
          End If
       End If
     End If
    End Sub

    Private Sub ImgSplitterH_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
        LeftCtl.Height = PictureH.Top - LeftCtl.Top
        ImgSplitterV.Height = LeftCtl.Height
        RightCtl.Height = LeftCtl.Height
        ImgSplitterH.Top = PictureH.Top
        BottomCtl.Height = FormX.Height - ImgSplitterH.Top - BottomMargin - SplitterHW - 400 - 5
        BottomCtl.Top = PictureH.Top + SplitterHW
        PictureH.Visible = False
        mbMoving = False
    End Sub

    Private Sub ImgSplitterV_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    PictureV.Visible = True
    With ImgSplitterV
         PictureV.Move .Left, .Top - 10, .Width / 2, .Height
    End With
    mbMoving = True
    End Sub

    Private Sub ImgSplitterV_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbLeftButton Then
       If mbMoving Then
          If X + ImgSplitterV.Left < LeftCtl.Left + MinWidth Then
             PictureV.Left = LeftCtl.Left + MinWidth
          ElseIf X + ImgSplitterV.Left > FormX.Width - SplitterHW - RightMargin - MinWidth - iErrorXY Then
             PictureV.Left = FormX.Width - SplitterHW - RightMargin - MinWidth - iErrorXY
          Else
             PictureV.Left = X + ImgSplitterV.Left
          End If
       End If
       PictureV.Height = LeftCtl.Height
    End If
    End Sub

    Private Sub ImgSplitterV_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    ImgSplitterV.Left = PictureV.Left
    LeftCtl.Width = PictureV.Left - LeftCtl.Left
    RightCtl.Width = FormX.Width - LeftCtl.Width - SplitterHW - LeftMargin - RightMargin - iErrorXY '- iError - 200
    RightCtl.Left = PictureV.Left + SplitterHW
    PictureV.Visible = False
    mbMoving = False
    End Sub

    至此该部件创建完成。
        接下来创建标准工程,并在窗体上绘制任意三个控件,如: TreeView、ListView、DataGrid,并编写
    如下代码测试 EasyViews 部件的类 SplitView:

    Option Explicit
    Dim x As New EasyViews.SplitView
    Private Sub Form_Load()
    '...
    x.TopMargin = 500 ' Toolbar1.Height + 100
    x.LeftMargin = 1000
    x.RightMargin = 1000
    x.BottomMargin = 500 'StatusBar1.Height
    x.MinHeight = 1000
    x.MinWidth = 1200
    x.Create TreeView1, ListView1, DataGrid1
    '...
    End Sub


    例1:使用过 Delphi 和 PB 的人应该知道,她们的 Form 和 Window 不需编程,即可实现滚动窗口。而在
        VB 中要实现滚动窗口则需要编写一些代码了,可参阅 MSDN:
        《Scroll Bar 控件方案:创建可滚动的图形视口》,现将其加工移植为 ActiveX Dll
        部件:
            创建 ActiveX Dll(命名为: EasyViews )工程,并在类模块 (命名为:ScrollView) 中添加如下
            代码:

    Option Explicit
    Dim Picture1 As PictureBox
    Dim Picture2 As PictureBox
    Dim Picture3 As PictureBox

    Dim WithEvents HScroll1 As HScrollBar
    Dim WithEvents VScroll1 As VScrollBar
    Dim WithEvents FormX As Form

    Dim iWidth As Integer
    Dim iHeight As Integer
    Dim iLeft As Integer
    Dim iTop As Integer

    Dim iLeftMargin As Integer
    Dim iRightMargin As Integer
    Dim iTopMargin As Integer
    Dim iBottomMargin As Integer

    Dim bAlignForm As Boolean

    Const iErrorXY = 135
    Const dXY = 60

    Public Sub Create(PictureBox As Object, Optional bAlignFormX As Boolean = True)
    Set Picture2 = PictureBox
    Set FormX = PictureBox.Container
    bAlignForm = bAlignFormX
    FormX_Load
    End Sub

    Private Sub FormX_Load()
    Dim temp As String

    temp = "DynamicPicture1"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.PictureBox", temp, FormX
    On Error GoTo 0
    With FormX.Controls.Item(temp)
         .Visible = True
    End With
    Set Picture1 = FormX.Controls.Item(temp)

    temp = "DynamicPicture3"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.PictureBox", temp, FormX
    On Error GoTo 0
    With FormX.Controls.Item(temp)
         .Visible = True
    End With
    Set Picture3 = FormX.Controls.Item(temp)

    temp = "DynamicHScroll1"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.HScrollBar", temp ', FormX
    On Error GoTo 0
    With FormX.Controls.Item(temp)
         .Visible = True
    End With
    Set HScroll1 = FormX.Controls.Item(temp)

    temp = "DynamicHScroll1"
    On Error GoTo ErrorHandler
    FormX.Controls.Add "VB.VScrollBar", temp ', FormX
    With FormX.Controls.Item(temp)
         .Visible = True
    End With
    Set VScroll1 = FormX.Controls.Item(temp)

    HScroll1.TabStop = False
    VScroll1.TabStop = False
    Set Picture1.Container = Picture3
    Set HScroll1.Container = Picture3
    Set VScroll1.Container = Picture3
    Set Picture2.Container = Picture1
    'Picture3.BorderStyle = 0
    Picture1.BorderStyle = 0
    Picture2.BorderStyle = 0
    If Not bAlignForm Then
       Picture3.Move Left, Top, Width, Height
       HScroll1.Move 0, Picture3.Height - HScroll1.Height - dXY, Picture3.Width - VScroll1.Width - dXY
       VScroll1.Move Picture3.Width - VScroll1.Width - dXY, 0, VScroll1.Width, Picture3.Height - HScroll1.Height - dXY
       Picture1.Move 0, 0, Picture3.Width - VScroll1.Width - dXY, Picture3.Height - HScroll1.Height - dXY
       Picture2.Move 0, 0
       HScroll1.LargeChange = HScroll1.Max / 5
       VScroll1.LargeChange = VScroll1.Max / 5
       If Picture1.Height >= Picture2.Height Then
          HScroll1.Width = Picture3.Width - dXY
          Picture1.Width = Picture3.Width - dXY
       End If
       If Picture1.Width >= Picture2.Width Then
          VScroll1.Height = Picture3.Height - dXY
          Picture1.Height = Picture3.Height - dXY
       End If
       HScroll1.Max = Picture2.Width - Picture1.Width '+ 10 '+ dXY
       VScroll1.Max = Picture2.Height - Picture1.Height ' + 10 '+ dXY
       HScroll1.SmallChange = 100
       VScroll1.SmallChange = 100
       HScroll1.Visible = (Picture1.Width < Picture2.Width)
       VScroll1.Visible = (Picture1.Height < Picture2.Height)
    End If
    Exit Sub
    ErrorHandler:
    temp = temp & "X"
    Resume
    End Sub

    Private Sub FormX_Resize()
    On Error Resume Next
    If bAlignForm Then
       Picture3.Move LeftMargin, TopMargin, FormX.Width - LeftMargin - RightMargin - iErrorXY, FormX.Height - TopMargin - BottomMargin - iErrorXY - iErrorXY - iErrorXY
       HScroll1.Move 0, Picture3.Height - HScroll1.Height - dXY, Picture3.Width - VScroll1.Width - dXY
       VScroll1.Move Picture3.Width - VScroll1.Width - dXY, 0, VScroll1.Width, Picture3.Height - HScroll1.Height - dXY
       Picture1.Move 0, 0, Picture3.Width - VScroll1.Width - dXY, Picture3.Height - HScroll1.Height - dXY
       Picture2.Move 0, 0
       HScroll1.LargeChange = HScroll1.Max / 5
       VScroll1.LargeChange = VScroll1.Max / 5
       If Picture1.Height >= Picture2.Height Then
          HScroll1.Width = Picture3.Width - dXY
          Picture1.Width = Picture3.Width - dXY
       End If
       If Picture1.Width >= Picture2.Width Then
          VScroll1.Height = Picture3.Height - dXY
          Picture1.Height = Picture3.Height - dXY
       End If
       HScroll1.Max = Picture2.Width - Picture1.Width ' + dXY
       VScroll1.Max = Picture2.Height - Picture1.Height ' + dXY
       HScroll1.SmallChange = 100
       VScroll1.SmallChange = 100
       HScroll1.Visible = (Picture1.Width < Picture2.Width)
       VScroll1.Visible = (Picture1.Height < Picture2.Height)
    End If
    End Sub

    Private Sub HScroll1_Change()
    Picture2.Left = -HScroll1.Value
    End Sub

    Private Sub VScroll1_Change()
    Picture2.Top = -VScroll1.Value
    End Sub

    Public Property Get Width() As Integer
           Width = iWidth
    End Property

    Public Property Let Width(ByVal vNewValue As Integer)
           iWidth = vNewValue
    End Property

    Public Property Get Height() As Integer
           Height = iHeight
    End Property

    Public Property Let Height(ByVal vNewValue As Integer)
           iHeight = vNewValue
    End Property

    Public Property Get Left() As Integer
           Left = iLeft
    End Property

    Public Property Let Left(ByVal vNewValue As Integer)
           iLeft = vNewValue
    End Property

    Public Property Get Top() As Integer
           Top = iTop
    End Property

    Public Property Let Top(ByVal vNewValue As Integer)
           iTop = vNewValue
    End Property

    Public Property Get LeftMargin() As Integer
           LeftMargin = iLeftMargin
    End Property

    Public Property Let LeftMargin(ByVal vNewValue As Integer)
           iLeftMargin = vNewValue
    End Property

    Public Property Get RightMargin() As Integer
           RightMargin = iRightMargin
    End Property

    Public Property Let RightMargin(ByVal vNewValue As Integer)
           iRightMargin = vNewValue
    End Property

    Public Property Get TopMargin() As Integer
           TopMargin = iTopMargin
    End Property

    Public Property Let TopMargin(ByVal vNewValue As Integer)
           iTopMargin = vNewValue
    End Property

    Public Property Get BottomMargin() As Integer
           BottomMargin = iBottomMargin
    End Property

    Public Property Let BottomMargin(ByVal vNewValue As Integer)
           iBottomMargin = vNewValue
    End Property

    至此该部件创建完成。
        接下来创建标准工程,并在窗体上绘制一 PictureBox(Picture1) 控件,再绘制一定数量的各种控件
    在该 PictureBox 控件内,并编写如下代码测试 EasyViews 部件的类 ScrollView :

    Option Explicit
    Dim x As New EasyViews.ScrollView
    Dim y As New EasyViews.ScrollView
    Private Sub Form_Load()
    '...
    x.Left = 1000
    x.Top = 200
    x.Height = 3000
    x.Width = 4000
    x.TopMargin = 3000
    x.LeftMargin = 500
    x.RightMargin = 500
    x.BottomMargin = 600
    x.Create Picture2 ', False

    y.Left = 2000
    y.Top = 300
    y.Height = 2500
    y.Width = 4000
    'y.TopMargin = 1000
    y.LeftMargin = 1000
    y.RightMargin = 1000
    y.BottomMargin = 4000
    y.Create Picture1, False

    '...
    End Sub


        该方案使调用部件的主程序代码简洁明了,使实现界面控制的"代码部件"与实现其它功能的代码分离,
    界限分明、一目了然。

  • 相关阅读:
    linux 命令 # tar zcvf Work.tar.gz Work
    ODBC
    vmware 与机器共享
    关机!!!
    reador哦
    asp.net的三层架构图
    十大著名黑客——阿德里安拉莫
    十大著名黑客——查德斯德尔曼
    十大著名黑客——埃里克雷蒙德
    十大著名黑客——George Hotz
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2485770.html
Copyright © 2011-2022 走看看