首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪个地方是初始化代码的最佳地方?

哪个地方是初始化代码的最佳地方?
EN

Stack Overflow用户
提问于 2012-07-26 22:57:51
回答 4查看 1.8K关注 0票数 2

可能重复: Splash Screen Programatically Show a splash screen while a database connection (that might take a long time) runs

哪一个是初始化代码的最佳位置,例如加载INI文件?我首先要在屏幕上显示表单,以便用户知道应用程序正在加载,然后我才想调用冗长的函数,如LoadIniFile或IsConnectedToInternet (最后一个非常慢)。

OnCreate不是很好,因为表单还没有准备好,并且它不会出现在屏幕上。

我是这样做的,但我并不总是这么做:

代码语言:javascript
复制
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秒),表单才会显示。

代码语言:javascript
复制
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,它是我唯一的表单(主表单)。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-07-27 08:39:51

要做到这一点,一个简单的方法就是给自己发送一个信息。我一直都这么做

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2012-07-27 01:24:34

调用frmTest.Show之后,您可以调用frmTest.Update让它在屏幕上呈现,然后调用LateInitialize。但是,在调用Application.Run之前,主消息循环将不会运行,因此表单在此之前将无法执行任何其他操作。

另一个选项是使用表单的OnShow事件通过PostMessage()将自定义窗口消息发送回表单,然后在稍后收到该消息时让表单调用LateInitialize。这将允许窗体正常处理绘制消息,直到调用LateInitialize为止。

任何阻塞主线程超过几毫秒/秒的线程都应该移到单独的工作线程中(尤其是IsConnectedToInternet)。应该使用主线程来运行UI。

票数 3
EN

Stack Overflow用户

发布于 2012-07-27 07:44:32

变体1:使用延迟1秒的TTimer,从TTimer中的主窗体的OnShow运行它--进行初始化--这将给大多数组件初始化和绘制变体1.1的时间:在函数中使用消息方法,并从OnShow调用Win API PostMessage (但不是SendMessage aka PostMessage)。这看起来似乎更便宜,但更快捷。然而,在表单上的某个复杂组件完全自行绘制之前,有时可能会收到“立即执行”的消息。

变体2:使用线程(OmniThreadsLib,甚至普通的TThread)从MainForm OnCreate启动它,让它在后台准备所有数据,然后启用所有需要的按钮、菜单等等--如果您有长且阻塞的函数,那么这是最好的方法。

变体3:在显示主表单之前使用SplashScreen。这很好,因为用户还没有看到该应用程序。这是很糟糕的原因-人们开始觉得你的程序是缓慢的。谷歌Chrome被告知在第一分钟将其主要形式画成图片,只是为了看上去“我们已经开始了”,即使是实际的控件也会在一段时间后准备就绪。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11679235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档