在我的Delphi应用程序完成初始化后,我应该将代码放在哪里执行一次?

ros*_*mcm 7 forms delphi events show delphi-2006

我的应用程序完成初始化并创建了主窗体后,我想要执行的功能.我确实在表单OnShow事件中有代码(称为ProcedureX),但我刚刚注意到它被调用了两次,因为OnShow正在触发两次.它在主程序DPR调用时触发:

Application.CreateForm(TMainForm, MainForm) ;  
Run Code Online (Sandbox Code Playgroud)

正如我所料.但在那之后,当我从包含表格屏幕位置的INI文件中读取内容时,我有一个电话:

MainForm.position := poScreenCenter ;
Run Code Online (Sandbox Code Playgroud)

这样,它会再次触发OnShow事件.

我在哪里可以调用ProcedureX,必须只调用一次,并且需要在执行之前创建主表单?

Mar*_*ema 9

如果您的代码只需要为每个表单创建运行一次(或者每个应用程序运行一次,并且每个应用程序运行只创建一次表单),请将代码放在表单的OnCreate处理程序中.这是它的自然之地.

如今(自从我想到D3)OnCreate在AfterConstruction方法的构造过程结束时触发.仅当您将OldCreateOrder设置为True(默认情况下为False)时,您可能会遇到麻烦,因为这会使OnCreate在Create构造函数的末尾触发.


Fra*_*ois 6

表单的正常执行顺序是:

  • AfterConstruction:当表单及其组件完全使用其所有属性创建时.
  • OnShow:每当Form准备好显示时(并且,是的,任何导致CM_SHOWINGCHANGED可以触发的更改OnShow)
  • Activate:每当Form获得焦点时

因此,根据您在ProcedureX中的需要,AfterConstruction可能就足够了,并且只执行一次; 只需覆盖它并在之后添加ProcedureX inherited.它会在之后OnCreate.

如果不是这种情况,您可以将自定义消息发布到您的表单中AfterConstruction,它将排队并在处理完其他消息后到达您的自定义处理程序.

在这两种情况下,您都不需要额外的布尔字段.


小智 6

@Sertac,

FRUNOnce领域真的没有必要; 只需将OnShow = NIL作为FormShow方法的第一行.

仅供参考,"运行一次"成语 - 在事件处理程序的第一行中将事件处理程序字段设置为NIL - 对于在表单完全初始化后使某些代码启动并运行也非常有用.将代码放在FormActivate方法中,并且作为方法的第一行,设置OnActivate = NIL.

  • 只有在事件处理程序中没有别的事情可做才有可能.但是,如果您在处理程序中有代码,只要您取消隐藏表单就可以运行它,那么您就无法处理该处理程序. (5认同)

Ser*_*yuz 5

第一次调用该过程后,您可以测试并设置标志。就像这样:

type
  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
  private
    FRunOnce: Boolean;
  public
    [...]

[...]

procedure TForm1.FormShow(Sender: TObject);
begin
  if not FRunOnce then begin
    FRunOnce := True;
    ProcedureX;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

  • @sergeant - 嗯,这是[记录](http://docwiki.embarcadero.com/RADStudio/en/Methods#Constructors)行为。 (2认同)

WeG*_*ars 5

您可以在 DPR 文件中的 Application.CreateForm 之后添加一个过程。将初始化所需的所有代码放入该过程中。当您的应用程序中有多个表单时效果最佳。

此外,如果初始化需要很多时间,它会让程序在屏幕上显示表单,以便用户知道应用程序正在加载。

例子:

PROGRAM MyProgram;
begin
    Application.Initialize;
    Application.CreateForm(TMyForm, MyForm);
    MyForm.Show;

    LateInitialize;        <----------- here

    Application.Run;
end. 
Run Code Online (Sandbox Code Playgroud)