如何在运行时加速批量创建控件?

时间:2009-12-16 15:39:29

标签: vb6

我坚持使用VB6,我正在使用Form.Controls.Add(...)在运行时创建一堆控件。

不幸的是,这似乎是一个非常缓慢的过程,伴随着大量的闪烁。

有没有办法加快这个过程?也许有可能以某种方式通知VB6我正在进行大量插入新控件。

4 个答案:

答案 0 :(得分:5)

您可以像这样使用隐藏的图片框

Set oCtl = Controls.Add("VB.TextBox", "txtMy1", picHidden)

然后你可以显示最快的容器,也可以隐藏控件并像这样重置容器

oCtl.Visible = False
Set oCtl.Container = Form1 ' or picHidden.Container

在任何情况下,您都可以使用隐藏的容器来减少闪烁。

答案 1 :(得分:3)

我已经使用了控制数组。创建您将需要的每种控件类型的单个实例 - 文本框,标签,下拉列表等。将每个控件的Index属性设置为0,(将每个控件转换为控件数组的基本控件) 。现在将其他属性设置为对应用程序中的每种控件类型有意义的属性。这些属性将在创建时应用于每个新控件。确保将Visible属性设置为False。

然后,使用Load语句在运行时添加控件。适当地定位它们,设置任何唯一属性,加载数据等,然后当完成所有操作时,通过索引扫描每个控件数组并将每个控件上的Visible属性设置为True。这足够快以至于避免闪烁,至少对于合理数量的控制而言。我用这种方式处理了近200个控件而没有闪烁。

此外,如果/当您需要使用新数据重建表单时,而不是使用Unload销毁控件,然后重新创建新控件,只需使它们全部不可见,并根据需要重复使用。以这种方式调整每个控件的属性要快得多,而不是每次都从头开始创建它们。

确实,您需要为每个控件数组的长度管理一个索引,以告诉您是否可以重用或需要创建一个新索引,但是一些辅助函数可以大大简化必要的跟踪。像这样:

Set newTextBox = GetNextTextBox

其中GetNextTextBox函数处理可用的总文本框控件的跟踪,以及哪一个是“下一个”,以便它可以决定是否可以重用现有文件框或者必须创建一个新文件框。

您可能还有一些函数,例如ResetTextBoxes,它使所有文本框都不可见,并重置“下一个可用”计数器。

答案 2 :(得分:3)

创建控件时禁用表单有帮助。如果它是实用的,它将有助于在该表单上实际设置Visible = False。

答案 3 :(得分:1)

我经常使用API​​调用LockWindowUpdate在添加大量项目时禁用列表框中的绘图。它大大加快了加载速度,并且易于声明和使用。我想它对于一个表格也会起作用。但是因为Ken White向我指出this article解释了为什么使用LockWindowUpdate是错误的我开始修改我的代码以使用SendMessage。到目前为止,它似乎与LockWindowUpdate一样在程序中起作用。

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const WM_SETREDRAW = &HB

Private Sub AddMyControls()

    ' The SendMessage function returns 0 for this message if successful,
    ' instead of using Call assign the return to a variable to check the success

    Call SendMesssage(Me.hwnd, WM_SETREDRAW, False, 0) ' prevent re-drawing while adding controls
    ' .... add controls

    ' It might be nice to know if the function was successful here
    ' or re-drawing might not be re-enabled and the user would wonder what's up
    Call SendMesssage(Me.hwnd, WM_SETREDRAW, True, 0)  ' re-enable drawing

End Sub