Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a form before the MainForm?

I want to create a splash screen (before the main form) that will be shown for x seconds but I don't want to delay the creation of the main form with x seconds.

So, I create the splash screen form, create the main form then after x seconds I close the splash form.
From what I understand the first form created with CreateForm is the main form. Is this right?

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.

Closing the splash form
The splash screen has a TTimer. The timer does some animation in the splash form and after x seconds it closes the form:

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

However, the application leaks mem at shutdown:

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

It looks like the frmSplash is not actually freed.

like image 798
Server Overflow Avatar asked Aug 10 '17 10:08

Server Overflow


2 Answers

Add an OnClose event to the splash form and set

Action := caFree;
like image 176
Uwe Raabe Avatar answered Nov 12 '22 19:11

Uwe Raabe


The splash form leaks because nothing destroys it. Some options:

  • Pass the Application object as the owner of the splash form when you create it.
  • Manually destroy it.
  • Ignore the leak. It doesn't much matter since you only create one splash form so failing to destroy it won't lead to any great consumption of resources.

With the first option the splash form won't be destroyed until the application ends. That's not all that different from intentionally leaking the form.

Choosing to destroy the form manually is a little more tricky. You'd want to do that when you close the splash form but you can't destroy an object from one of its own event handlers. So instead you could call the Release method of the form and queue the form's destruction. If you go this way you need to ensure that the form is destroyed even if the timer never expires. Making the form be owned by the Application object would get that done.

like image 35
David Heffernan Avatar answered Nov 12 '22 18:11

David Heffernan