本帖最后由 bcrun 于 2012-02-29 20:21:26 编辑

解决方案 »

  1.   

    dim t1 as textbox,t2 as textboxcname=
    set t1=controls.add(Controls.Add("VB.textbox", cname)
    set t1.container=frame1'假设frame1已经存在cname=。
    set t2=controls.add(Controls.Add("VB.textbox", cname)
    set t2.container=frame2'假设frame2已经存在
      

  2.   

    楼上的方案没有解决分组问题,我之所以想分组是为了后续的操作,比如说在某个frame里单独添加或删除textbox控件,以及将这些控件存入数据库(每个text代表了不同的存在)。我曾设想过先定义多个类,即M1、M2Mn,n的最大值可以预估不会太大,写代码的话还可以接受,但是那样太繁琐,想找一个简单的方式。
      

  3.   

    dim tx as textboxcname="T1"
    set tx=controls.add(Controls.Add("VB.textbox", cname)
    set tx.container=frame1'假设frame1已经存在
    tx.tag="g1"cname="T2"
    set tx=controls.add(Controls.Add("VB.textbox", cname)
    set tx.container=frame1'假设frame1已经存在
    tx.tag="g1"
    .......
    '现在T1,T2都被标记为g1cname="TG1"
    set tx=controls.add(Controls.Add("VB.textbox", cname)
    set tx.container=frame1'假设frame1已经存在
    tx.tag="g2"cname="TG2"
    set tx=controls.add(Controls.Add("VB.textbox", cname)
    set tx.container=frame1'假设frame1已经存在
    tx.tag="g2"
    '现在TG1,TG2都被标记为g2’以此类推,通过tag属性分辨是属于哪个组,使用时候,看tag值,就知道是属于哪个组
      

  4.   

    用空间数组呗以 Frame1 为例,在Frame1上加一个辅助用的 TextBox 控件,假设名称为 TextFrame1,将该控件的 Index 属性值设置为 0,Visible 设置为 False
    然后写如下代码:Option ExplicitPrivate Sub Command1_Click()
        Dim i As Integer
        
        For i = 1 To 9
            Load TextFrame1(i)
            
            TextFrame1(i).Left = 100
            TextFrame1(i).Height = 45
            TextFrame1(i).Width = 3000
            
            TextFrame1(i).Top = TextFrame1(i - 1).Top + TextFrame1(i).Height + 50
            
            TextFrame1(i).Visible = True
        Next
        
    End SubPrivate Sub Form_Load()
        TextFrame1(0).Visible = False
        
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        Dim i As Integer
        
        For i = 1 To 9
            Unload TextFrame1(i)
        Next
        
    End Sub
    其它 Frame 的 TextBox 们类似处理
      

  5.   

    sorry 空间数组 ==> 控件数组  万恶的输入法啊。
      

  6.   

    这样我也想过,只是频繁的删改操作之后的存储每个textbox的信息会变得比较麻烦,所以希望能有成功分组的方法。
      

  7.   

    不知您注意到没有,frame控件也是动态添加的,并且允许手动删除它。
      

  8.   

    sorry,真没注意到重写了动态创建的代码,如下,不知是否是你需要的,没怎么调试,看看能运行就贴上来了,理论上来说一定有bug,见谅Option ExplicitPrivate Type T_FRA_TBS
        fra As frame
        tbs() As TextBox
    End TypePrivate fra_tbs() As T_FRA_TBSPrivate Sub Command1_Click()
        If True = delete_frame(3) Then
            MsgBox "Delete Frame Done"
        Else
            MsgBox "Delete Frame Failed"
        End If
    End SubPrivate Sub Command2_Click()
        If True = delete_tbx(6, 2) Then
            MsgBox "Delete TextBox Done"
        Else
            MsgBox "Delete TextBox Failed"
        End If
    End SubPrivate Sub Form_Load()
        Dim fra_count As Long
        
        ' 假设通过函数 get_frame_count 来获取 frame 数量
        fra_count = get_frame_count(0)
        ReDim fra_tbs(fra_count - 1)    ' 创建 frame
        Dim fra_name As String
        Dim left As Long, top As Long
        Dim i As Long
        For i = 0 To fra_count - 1
            fra_name = "fra_" + Trim$(Str(i + 1))
        
            If (0 = i) Then
                Set fra_tbs(i).fra = create_frame(fra_name, , , , , Me)
            ElseIf (1 = i) Then
                left = fra_tbs(0).fra.left + 300 + fra_tbs(0).fra.width
                top = fra_tbs(0).fra.top
                
                Set fra_tbs(i).fra = create_frame(fra_name, , , left, top, Me)
            Else
                If (0 = (i Mod 2)) Then
                    left = fra_tbs(0).fra.left
                Else
                    left = fra_tbs(1).fra.left
                End If
                
                top = fra_tbs(i - 2).fra.top + fra_tbs(i - 2).fra.height + 100
                
                Set fra_tbs(i).fra = create_frame(fra_name, , , left, top, Me)
            End If
            
            fra_tbs(i).fra.Caption = fra_name
        
            Dim tbs_count As Long
            ' 假设通过函数 get_textbox_count 来获取 textbox 数量
            tbs_count = get_textbox_count(i + 1)
            ReDim fra_tbs(i).tbs(tbs_count - 1)
            
            fra_tbs(i).fra.Caption = fra_tbs(i).fra.Caption + " (" + Trim$(Str(tbs_count)) + ")"
            
            ' 为当前 frame 创建 textbox
            Dim tbx_name As String
            Dim j As Long
            For j = 0 To tbs_count - 1
                tbx_name = "tbx_" + Trim$(Str(i + 1)) + "_" + Trim$(Str(j + 1))
                
                If (0 = j) Then
                    top = 500
                Else
                    top = fra_tbs(i).tbs(j - 1).top + fra_tbs(i).tbs(j - 1).height + 50
                End If
                
                Set fra_tbs(i).tbs(j) = create_tbx(tbx_name, , , , top, fra_tbs(i).fra)
            Next
            
        NextEnd SubPrivate Function get_frame_count(ByVal condition As Variant) As Long
        ' do sth. to get counts
        
        ' 假设有 8 个 frame
        get_frame_count = 8End FunctionPrivate Function get_textbox_count(ByVal condition As Variant) As Long    ' do sth. to get counts
        
        ' 假设每个frame拥有的 textbox 数量分别如下
        ' 3, 6, 2, 5, 2, 7, 4, 9
        
        Select Case condition
            Case Is = 1
                get_textbox_count = 3
            Case Is = 2
                get_textbox_count = 6
            Case Is = 3
                get_textbox_count = 2
            Case Is = 4
                get_textbox_count = 5
            Case Is = 5
                get_textbox_count = 2
            Case Is = 6
                get_textbox_count = 4
            Case Is = 7
                get_textbox_count = 5
            Case Is = 8
                get_textbox_count = 6
        End Select
    End Function'新建 frame 的函数
    Private Function create_frame(ByVal fra_name As String, _
                                  Optional ByVal width As Long = 6200, _
                                  Optional ByVal height As Long = 3000, _
                                  Optional ByVal left As Long = 100, _
                                  Optional ByVal top As Long = 100, _
                                  Optional container As Object = Nothing) As frame
        Dim frame_new As frame
        Set frame_new = Nothing
        
        If (Not (container Is Nothing)) Then
            Set frame_new = Controls.Add("VB.Frame", fra_name, container)
        Else
            Set frame_new = Controls.Add("VB.Frame", fra_name)
        End If
        
        With frame_new
            .width = width
            .height = height
            .left = left
            .top = top
            .Visible = True
        End With
        
        Set create_frame = frame_new
    End Function'删除 frame 的函数
    Private Function delete_frame(ByVal fra_index As Long) As Boolean
        If (fra_index > UBound(fra_tbs)) Then
            delete_frame = False
            Exit Function
        End If
        
        Controls.Remove (fra_tbs(fra_index).fra.Name)
        
        ' 可以考虑用 CopyMemory API 优化
        Dim i As Long
        For i = (fra_index + 1) To UBound(fra_tbs)
            fra_tbs(i - 1) = fra_tbs(i)
        Next    ReDim Preserve fra_tbs(UBound(fra_tbs) - 1)
        
        delete_frame = True
    End Function'新建 textbox 的函数
    Private Function create_tbx(ByVal tbx_name As String, _
                                Optional ByVal width As Long = 5500, _
                                Optional ByVal height As Long = 300, _
                                Optional ByVal left As Long = 300, _
                                Optional ByVal top As Long = 30, _
                                Optional container As Object = Nothing) As TextBox
        Dim tbx_new As TextBox
        Set tbx_new = Nothing
        
        If (Not (container Is Nothing)) Then
            Set tbx_new = Controls.Add("VB.TextBox", tbx_name, container)
        Else
            Set tbx_new = Controls.Add("VB.TextBox", tbx_name)
        End If
        
        With tbx_new
            .width = width
            .height = height
            .left = left
            .top = top
            .Visible = True
        End With
        
        Set create_tbx = tbx_new
    End Function'删除 textbox 的函数
    Private Function delete_tbx(ByVal fra_index As Long, ByVal tbx_index As Long) As Boolean
        If (fra_index > UBound(fra_tbs)) Then
            delete_tbx = False
            Exit Function
        End If
        
        If (tbx_index > UBound(fra_tbs(fra_index).tbs)) Then
            delete_tbx = False
            Exit Function
        End If    ' 可以考虑用 CopyMemory API 优化
        Dim i As Long
        For i = (tbx_index + 1) To UBound(fra_tbs(fra_index).tbs)
            fra_tbs(fra_index).tbs(i - 1) = fra_tbs(fra_index).tbs(i)
        Next    ReDim Preserve fra_tbs(fra_index).tbs(UBound(fra_tbs(fra_index).tbs) - 1)    Controls.Remove (fra_tbs(fra_index).tbs(tbx_index).Name)
            
        delete_tbx = True
    End Function
      

  9.   


    谢谢你的热心,我想知道这种方法对事件的响应是如何达到的,还好我已经用另一种方法调试好了,不过用的是是每一次都遍历窗体的方法,感觉很费事。现在对动态控件的响应是这么做的,Private WithEvents NewFrame As Frame'添加
    Private WithEvents NewText As TextBox'新建Frame控件
    Public Property Set AddFrame(ByVal fData As Frame)
       Set NewFrame = fData
    End Property
    Public Property Get AddFrame() As Frame
        Set AddFrame = NewFrame
    End PropertyPrivate Sub NewFrame_Click()’响应建立的frame的事件,比如新建、删除frame及新建删除textbox,你给出的方法好像不能像控件数组一样响应事件(还是我基础太差了),晕啊
    MsgBox NewFrame.Name
    End Sub'可惜WithEvents不能定义数组,正在想办法
      

  10.   


    dim F() as class1'定义frame数组
    dim T() as  class1’定义textbox数组,问题出在这里,T()只能获取所有frame数组中的控件,不能分开,只能每次使用时判断
      

  11.   

    WithEvent 我也有用过,不过在数组上的确没试过,不过我看你的代码的意思,要响应一个 Click?是哪个Object要响应?Frame吗?点击Frame产生新的Frame?然后被产生的新的Frame也能响应这个Click事件?
    我可能没理解,不过我觉得你一开始说的从数据库读数据,然后分散到各个Frame及各个Frame中的TextBox里面,这个应该是后台自动完成的吧?需要响应什么事件呢?可能我真的没理解你的需求呢,能说明的话,说说看看呢?
      

  12.   

    可以说程序开始时没有任何frame,用户建立之后保存入数据库,之后每次程序启动读取数据库内容并还原frame及textbox的位置及内容,然后用户可以重新编辑,frame响应右键事件,添加删除frame及textbox。
      

  13.   


    程序使用了WithEvents,没找到替代的方法,现在使用遍历窗体控件的方式做出来了,感觉整合到整个程序里会拖长运行时间,老是感觉笨笨的,呵呵
      

  14.   

    考虑试下子 windows 消息吧