如何在MainForm之前创建表单?

时间:2017-08-10 10:27:17

标签: delphi splash-screen delphi-xe7 splash

我想创建一个启动画面(在主窗体之前),它将显示x秒但我不想延迟创建主窗体x秒。

所以,我创建了初始屏幕,然后创建主窗体,然后在x秒后关闭启动窗体 据我所知,使用CreateForm创建的第一个表单是主表单。这是正确的吗?

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := FALSE;
  Application.Title := AppName;
  frmSplash:= TfrmSplash.Create(NIL);         <----- not main form??
  Application.CreateForm(TfrmMain, frmMain);  <----- main form??
  frmMain.LateInitialization;
  frmMain.show;
  Application.Run;
end.

关闭飞溅形式
启动画面有一个TTimer。计时器以启动形式执行一些动画,并在x秒后关闭表单:

procedure TfrmSplash.CloseSplashForm;
begin
 Timer.Enabled:= FALSE;
 Close;        <-- I do see the program reaching this point
end;

但是,应用程序会在关闭时泄漏内存:

5 - 12 bytes: TMoveArrayManager<System.Classes.TComponent> x 4, Unknown x 2
13 - 20 bytes: TObservers x 1, TList x 3, Unknown x 3
21 - 36 bytes: TComponent.GetObservers$942$ActRec x 1, TPen x 2, TIconImage x 1, TPadding x 1, TBrush x 3, TTouchManager x 2, TMargins x 2, TSizeConstraints x 2, TList<System.Classes.TComponent> x 4, UnicodeString x 3, Unknown x 6
37 - 52 bytes: TDictionary<System.Integer,System.Classes.IInterfaceList> x 1, TPicture x 1, TGlassFrame x 1, TFont x 4
53 - 68 bytes: TIcon x 1
69 - 84 bytes: TControlScrollBar x 2
85 - 100 bytes: TTimer x 1
101 - 116 bytes: TControlCanvas x 2
149 - 164 bytes: Unknown x 2
437 - 484 bytes: TImage x 1
917 - 1012 bytes: TfrmSplash x 1

看起来frmSplash实际上并没有被释放。

3 个答案:

答案 0 :(得分:8)

OnClose 事件添加到启动窗体并设置

Action := caFree;

答案 1 :(得分:4)

飞溅形式泄漏,因为没有任何东西会破坏它。一些选择:

  • 创建时,将Application对象作为splash表单的所有者传递。
  • 手动摧毁它。
  • 忽略泄漏。它没什么关系,因为你只创建一个启动表单,因此未能销毁它不会导致任何大量的资源消耗。

使用第一个选项,在应用程序结束之前,不会销毁splash表单。这与故意泄露表格并没有什么不同。

选择手动销毁表单有点棘手。关闭启动窗体时,您可能希望这样做,但是您无法从其自己的事件处理程序中销毁对象。因此,您可以调用表单的Release方法并对表单的销毁进行排队。如果你这样做,你需要确保即使计时器永不过期也要销毁表单。使表单由Application对象拥有将完成。

答案 2 :(得分:3)

多年以来我一直使用这个结构:

program MyProg;
uses
  Vcl.Forms,
  MainFrm in 'MainFrm.pas' {Zentrale},
  // Your Forms are here
  SplashFrm in 'SplashFrm.pas' {Splash};

{$R *.res}

var
  Sp: TSplash;

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.Title := 'XXXXXX';

{$IFDEF RELEASE}
  SP := TSplash.Create(nil);
  SP.Show;
  SP.Update;
{$ENDIF}

  Application.CreateForm(TZentrale, Zentrale);
  // ... and more Forms 

{$IFDEF RELEASE}
  SP.Hide;
  SP.free;
{$ENDIF}

  Application.Run;