但是有一个大问题:它很慢!创建控件不需要花时间,但设置Parent属性似乎非常耗时.
我已经尝试了几种方法来加快这个过程,但没有运气.我尝试过Enabled = False,Visible = False,DisableAlign,LockWindowUpdate,WM_SETREDRAW ……但似乎没有任何事情影响设置控件的Parent的耗时过程.
即使我们使用线程,这也需要时间,因为必须在Synchronize中调用VCL函数.
亲切的问候,
马格努斯
编辑:没有数据感知组件或GUI中触发的任何事件.我只是创建控件并显示它们.使用计时器我已经确定控件父(AControl.Parent:= AOwner)的分配是耗时的部分.
编辑2:如下面的答案所示,速度问题不是设置父级而是绘制控件.当我测试时间时,容器是可见的并且设置父级导致立即绘制控件.
编辑3:动态GUI的另一个耗时部分是将项目分配给组合框. ComboBox.Items.Assign(DataItems),其中DataItems不超过三到六个项目.
谢谢大家抽出时间帮助我!
解决方法
编辑:您应该在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控件.在我的系统上创建所有这些控件并设置它们的属性需要几十毫秒,但最后显示表单(将创建所有窗口)需要几百毫秒.由于这只能在主线程中完成,我怀疑使用多线程会对你有所帮助.