Delphi:应用程序初始化 - 最佳实践/方法

时间:2008-12-19 23:13:05

标签: forms delphi initialization datamodule

我经常遇到这种情况,我只是在寻找最佳实践/方法。我有一个包含数据库/数据模块的应用程序,并且想要在启动时启动数据库/数据集,而在设计时将“运行时活动”设置为true(数据库位置不同)。当应用程序启动时,还运行Web“检查更新”例程。

鉴于TForm事件序列以及各种试错的结果,我目前正在使用这种方法:

我使用在主窗体中设置的“Globals”记录来存储所有全局变量,有一个名为Globals.AppInitialized(boolean)的元素,并在主窗体的Initialization部分将其设置为False。

在主窗体的OnShow事件中(所有窗体都是在那时创建的),我测试了Globals.AppInitialized;如果它是假的,我运行我的“初始化”的东西,然后通过设置Globals.AppInitialized:= True完成。

这似乎工作得很好,但这是最好的方法吗?寻找别人的经验,想法和意见的见解。 TIA ..

7 个答案:

答案 0 :(得分:10)

我通常总是关闭主表单和主数据模块的所有表单的自动创建。

我了解到的一个技巧是将数据模块添加到项目中,允许它在主窗体之前自动创建和创建。然后,当您创建主窗体时,数据模块的onCreate将已经运行。

如果您的应用程序有一些代码要说,请设置控件的焦点(在创建时无法做到的事情,因为它“尚未显示”)然后创建用户消息并将其发布到您的oncreate中的表单。一旦处理了表单消息循环,就应该处理该消息(不保证)。例如:

const
  wm_AppStarted = wm_User + 101;


type
  Form1 = class(tForm)
    :
    procedure wmAppStarted(var Msg:tMessage); message wm_AppStarted;
  end; 

// in your oncreate event add the following, which should result in your wmAppStarted event firing.
PostMessage(handle,wm_AppStarted,0,0);

我想不出一次该消息从未被处理过,但是调用的本质是它被添加到消息队列中,如果队列已满,则它被“丢弃”。请注意存在边缘情况。

答案 1 :(得分:7)

您可能希望在表单创建调用之后和Application.Run之前直接干扰项目源(.dpr文件)。 (或者甚至更早的情况。)

这就是我通常处理这种初始化的方法:

...
Application.CreateForm(TMainForm, MainForm);    
...
MainForm.ApplicationLoaded; // loads options, etc..
Application.Run;
...

答案 2 :(得分:3)

我不知道这是否有用,但我的一些应用程序没有自动创建的任何表单,即它们在IDE中没有主表单。

使用Application对象作为其所有者创建的第一个表单将自动成为mainform。因此,我只自动创建一个数据模块作为加载器,并让这个数据模块决定创建哪些数据模块以及以什么顺序创建哪些表单。该数据模块有一个StartUp和ShutDown方法,它们在dpr中的Application.Run周围被称为“括号”。 ShutDown方法可以更好地控制关机过程。

当您为应用程序的不同用例设计不同的“主变量”时,这可能很有用,或者您可以使用某些配置文件来选择不同的主变形。

答案 3 :(得分:2)

Delphi中实际上没有“全局变量”这样的概念。所有变量都限定在它们所在的单位和使用该单位的其他单位。

只需将 AppInitialized Initialization 内容作为数据模块的一部分。基本上有一个类(或数据模块)来统治你所有的非UI东西(有点像One-Ring,除了不是所有邪恶之类的东西。)

或者你可以:

  • 从启动画面调用它。
  • 在登录期间执行
  • 在后台线程中运行“check for update” - 不要强迫他们立即更新 。有点像Firefox一样。

答案 4 :(得分:1)

我不确定我理解你为什么需要全局变量?现在我写的所有我的Delphi应用程序没有一个全局变量。即使我确实使用它们,每次应用程序也不会超过几个。

所以也许你需要先考虑为什么你真的需要它们。

答案 5 :(得分:1)

我使用主数据模块检查数据库连接是否正常,如果没有,则显示自定义组件表单以设置数据库连接,然后加载主表单:

Application.CreateForm(TDmMain, DmMain);

  if DmMain.isDBConnected then
    begin
      Application.CreateForm(TDmVisualUtils, DmVisualUtils);
      Application.CreateForm(TfrmMain, frmMain);
    end;

  Application.Run;

答案 6 :(得分:-1)

我使用的一个技巧是在主窗体上放置一个TTimer,将时间设置为300ms,并执行任何初始化(db登录,网络文件复制等)。启动应用程序会立即显示主窗体,并允许任何初始化“东西”发生。用户不会启动多个实例,他们会想“哦......我没有dbl-click ......我会再做一次..”