【发布时间】:2015-07-21 23:26:58
【问题描述】:
我在 FormMain 中打开 Form2.ShowModal。我希望应用程序在进行一些数据库访问时完整地显示 Form2(这与要显示的新数据无关)。但是,在执行 FormShow 时,只显示了外边框和一些损坏的部分,而 FormMain 的一些损坏的部分则显示出来了。太丑了。
我无法找到一种方法让 Delphi 立即重新绘制表单,然后执行耗时的 MyOpenData 过程。结束 MyOpenData 后一切正常。
procedure TForm2.FormShow(Sender: TObject);
begin
Invalidate;
Refresh;
MyOpenData; { needs some seconds of database accesses }
end;
替代方案:
procedure TForm2.FormShow(Sender: TObject);
begin
Invalidate;
Refresh;
SendMessage(Handle, wm_paint, 0, 0);
PostMessage(Handle, wm_OpenMyData, 0, 0); { executes well, but no solution)
end;
这也不起作用。我认为 SendMessage() 等待消息完成。但是在 MyOpenData 之前没有完成绘制。在程序完成之前,表格总是看起来很破损。除此之外,例程执行得很好。我尝试了所有这些命令的组合或单独。
我错过了什么?提前致谢!
如何启动打开表单时需要运行的耗时例程?
(Windows 7 64 位上的 Delphi XE7)
【问题讨论】:
-
您应该使用
class(TThread)在后台准备此数据,而不会破坏用户与表单的交互。我很多年都不做Delphi了,所以我就让你去做。这里有几个例子:stackoverflow.com/a/3456816/156811 -
在 alternative 中,删除前三行,这就是您的解决方案。 没有解决方案是什么意思?
-
@Havenard:MyOpenData() 不是线程安全的,但会经常访问 Form 和几个对象。但是,它应该在表单重新绘制以使其看起来完整之后运行。这就是我的问题所在。
-
@HJay - 推迟处理是正确的做法,您的表单甚至在 OnShow 中都不可见。删除第二个 sn-p 中的前三行,在过程 OpenMyData 中调用 'Update' 作为第一条语句。然后打开你的数据。
-
延迟执行将允许绘制窗口。当然,您仍然会阻塞主线程,因此您的窗口将无响应并且可能出现重影。将长时间运行的代码移至线程。永远不要尝试合成这样的绘画信息。你不能。只有系统可以。
标签: delphi delphi-xe7