可能重复:
Splash Screen Programatically
Show a splash screen while a database connection (that might take a long time) runs
哪个是初始化代码的最佳位置,例如加载INI文件?我想首先在屏幕上显示表单,以便用户知道应用程序正在加载,之后我想调用冗长的函数,如LoadIniFile或IsConnectedToInternet(最后一个非常慢)。
OnCreate并不好,因为表格尚未准备好,并且不会显示在屏幕上。
我这样做我DPR但总是不工作:
program Test;
begin
Application.Initialize;
Application.Title := 'Test app';
Application.CreateForm(TfrmTest, frmTest);
frmTest.Show; <---------------------- won't show
LateInitialize;
Application.Run;
end.
在执行LateInitialize(4-5秒)之前,表格不会显示。
procedure LateInitialize;
begin
CursorBussy;
TRY
// all this won't work also. the form won't show
frmTest.Visible:= TRUE;
Application.ProcessMessages;
frmTest.Show;
Application.ProcessMessages;
frmTest.BringToFront;
frmTest.Update;
Application.ProcessMessages;
DoSomethingLengthy; {4-5 seconds}
FINALLY
CursorNotBussy;
END;
end; <--------- Now the form shows.
是的,frmTest它是我唯一的形式(主要形式)。
答案 0 :(得分:3)
致电frmTest.Show
后,您可以致电frmTest.Update
让其在屏幕上呈现,然后再调用LateInitialize
。但是在调用Application.Run
之前,主消息循环将不会运行,因此在此之前表单将无法执行任何其他操作。
另一种选择是使用表单的OnShow
事件通过PostMessage()
将自定义窗口消息发布回表单,然后在表单中收到该消息时调用表单LateInitialize
晚点。这将允许表单正常处理绘制消息,直到调用LateInitialize
。
任何阻塞主线程超过几毫秒/秒的事情都应该转移到一个单独的工作线程中(尤其是像IsConnectedToInternet
这样的事情)。主线程应该用于运行UI。
答案 1 :(得分:2)
一种简单的方法是向自己发送消息。 我一直这样做
const
MSG_AFTERCREATE = WM_APP + 4711;
...
procedure OnCreate(Sender: TObject);
procedure AfterCreate(var message: TMessage); message MSG_AFTERCREATE;
...
Implementation
procedure OnCreate(Sender: TObject);
begin
PostMessage(Self.Handle, MSG_AFTERCREATE, 0, 0);
end;
procedure AfterCreate(var message: TMessage);
begin
//Do initializing here... the form is done creating, and are actually visible now...
end;
答案 2 :(得分:0)
很久以前,在很远的另一个论坛上,有人发布了以下内容来记录表格的生命周期。我发现它很有用,所以我在这里分享。
Create OnCreate
Show OnShow
Paint OnPaint
Activate OnActivate
ReSize OnResize
Paint OnPaint
Close query OnCloseQuery
Close OnClose
Deactivate OnDeactivate
Hide OnHide
Destroy OnDestroy
尝试OnActivate事件。