德尔福Win32 : Speed up dynamically created controls (Parent property)

标签 delphi user-interface dynamic

我们有一个由多个框架组成的 GUI,可以动态构建其内容。每个框架都会创建面板、标签、编辑、组合框等以用作输入字段。这工作得很好,我们还计划让每个框架在单独的线程中构建其内容。

但是有一个大问题:速度相当慢!创建控件不需要时间,但设置 Parent 属性似乎非常耗时。

我尝试了多种方法来加快该过程,但没有成功。我尝试过Enabled=False、Visible=False、DisableAlign、LockWindowUpdate、WM_SETREDRAW...但似乎没有什么能影响设置控件Parent的耗时过程。

即使我们使用线程,这也会花费一些时间,因为必须在 Synchronize 中调用 VCL 函数。

还有其他方法可以加快控件的创建和显示速度吗?

亲切的问候, 马格努斯

编辑: GUI 中没有数据感知组件或触发的任何事件。我只是创建控件并显示它们。使用计时器,我已将控件父级 (AControl.Parent := AOwner) 的分配确定为耗时的部分。

编辑2:如下面的答案所示,速度问题不是设置父项而是控件的绘制。当我测试时间时,容器可见并且设置父级会导致控件立即绘制。

编辑 3:动态 GUI 的另一个耗时部分是将项目分配给组合框。 ComboBox.Items.Assign(DataItems),其中 DataItems 不超过三到六个项目。

感谢大家花时间帮助我!

最佳答案

不要尝试使用多线程来创建控件或使用一般的 VCL。无论如何,这不会提高速度,但更重要的是,这对 VCL 来说是完全禁忌的。

编辑:您应该阅读 StackOverflow 上处理 VCL 和多线程的其他问题和答案,但简而言之:VCL 不是线程安全的,对控件的所有访问都必须在主线程的上下文中完成。因此,当使用多个线程时,您必须将几乎所有内容都包装在 Synchronize() 调用中,这实际上会序列化所有线程并进一步减慢速度。

您最好的选择是重组您的 UI,这样就不需要一次性创建所有内容。仅当首次显示时才按需创建所有帧。

编辑 2: 下面是一些测试代码,表明设置 Parent 属性并不是真正的问题,但创建所有控件(以及所需的所有消息处理)可能才是真正的问题。

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, x, y: integer;
  Edit: TEdit;
  Ticks: LongWord;
begin
  Visible := FALSE;
  DestroyHandle;

  try
    for i := 1 to 20 do begin
      y := 20 + i * 25;
      for j := 1 to 10 do begin
        x := (j - 1) * 100;

        Edit := TEdit.Create(Self);
        Edit.SetBounds(x, y, 98, 23);
        Edit.Parent := Self;
      end;
    end;
  finally
    Ticks := timeGetTime;
    Visible := TRUE;
    Caption := IntToStr(timeGetTime - Ticks);
  end;
end;

释放父窗体的句柄后,代码动态创建 200 个 TEdit 控件。在我的系统上创建所有这些控件并设置其属性需要花费 10 毫秒,但最终显示表单(将创建所有窗口)需要花费 100 毫秒。由于这只能在主线程中完成,我怀疑使用多个线程会对您有所帮助。

关于德尔福Win32 : Speed up dynamically created controls (Parent property),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/751318/

相关文章:

Delphi,Indy10,如何正确停止和清理连续流上的 readln

delphi - Delphi中指向指针的初始数组

sql - 查询不返回结果(Delphi、Oracle、DBExpress)

java - 重绘未按要求正常运行

c++ - 动态嵌套列表

delphi - X,Y 字符串的大量组合

java - Swing Java 如何制作多个按钮,在单击时执行不同的任务

c# - GUI 应用程序中的 Tcl channel

css - 我不明白如何在 div 中动态调整 ul 的大小

javascript - 使用 VueJs、Cordava 和 Javascript 进行动态组件插入