加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi Win32:加速动态创建的控件(父属性)

发布时间:2020-12-15 04:21:21 所属栏目:大数据 来源:网络整理
导读:我们有几个框架的GUI,可动态构建其内容.每个框架都会创建面板,标签,编辑,组合框等,以用作输入字段.这非常有效,我们还计划让每个框架在不同的线程中构建其内容. 但是有一个大问题:它很慢!创建控件不需要花时间,但设置Parent属性似乎非常耗时. 我已经尝试了
我们有几个框架的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控件.在我的系统上创建所有这些控件并设置它们的属性需要几十毫秒,但最后显示表单(将创建所有窗口)需要几百毫秒.由于这只能在主线程中完成,我怀疑使用多线程会对你有所帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读