哪个是初始化代码的最佳位置?

时间:2012-07-26 22:57:52

标签: delphi

  

可能重复:
  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它是我唯一的形式(主要形式)。

3 个答案:

答案 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事件。