17

I have a form that I use to show some information for some seconds. Is it ok for the form to free itself? Can I start a timer in the constructor, and then call self.free in the timer-event? Or will this potentially lead to trouble?

Shannon Matthews
  • 9,649
  • 7
  • 44
  • 75
Vegar
  • 12,828
  • 16
  • 85
  • 151
  • According to the manual, inside of event handlers, you MUST call Release instead of Close or Free. https://docwiki.embarcadero.com/Libraries/Sydney/en/Vcl.Forms.TCustomForm.Release – Gabriel Sep 06 '22 at 05:55

4 Answers4

31

In addition, with a form you can call Release.

It sends a CM_RELEASE message to the form. As a reaction it calls Free. The advantage of release is that there are no messages left for the form which could result in a crash.

Gabriel
  • 20,797
  • 27
  • 159
  • 293
Toon Krijthe
  • 52,876
  • 38
  • 145
  • 202
  • I think I will go for this one, in combination with setting the owner as a extra insurance. – Vegar Apr 02 '09 at 10:09
  • @Rigel, not exactly, Close uses CloseQuery which can be used to interrupt the process and it is not guaranteed to free the form. Depending on the cloise action, the form can also hide or minimize (Have a look at TCustomForm.Close in Vcl.Forms.pas. – Toon Krijthe Nov 30 '18 at 07:24
  • Yes. Of course. `Close` will or will not close the form, depending on how you set the close action. But I was speaking about something else: (if it set to caFree) `.Close` is as safe as `.Release`. I mean it will not create the problems that `.Free` will create. – Gabriel Nov 30 '18 at 09:03
18

You can make the form to free itself when it gets closed by the user or from code:

procedure TForm27.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TForm27.FormCreate(Sender: TObject);
begin
  Timer1.Enabled := True;
end;

procedure TForm27.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  Close;
end;

Make sure you supply an owner in the constructor incase the application shutdowns and the form is not destroyed at the time. The owner will free the form before freeing itself.

pani
  • 1,075
  • 6
  • 13
  • The more I think about it, the more I like the TCloseAction-idea. Maybe I should use that instead of release... – Vegar Apr 02 '09 at 20:32
  • 3
    if only forms had DefaultCloseAction properties, so pone could auto-free them without assigning event handlers. – Arioch 'The Jan 17 '13 at 07:57
1

I have a whole suite of objects that free themselves, and I've run various tests on them with no problems/leaks shown. A TForm might be more complex, but as long as Self.Free() is the last call made, you ought to be safe.

(For those wondering why on earth I have object that free themselves; I pass them around the system a lot, so I implemented by own reference counting scheme. When the last reference is released, so the object frees itself).

Drarok
  • 3,612
  • 2
  • 31
  • 48
0

This is exactly what is done with Interfaces.

Arafangion
  • 11,517
  • 1
  • 40
  • 72
  • 1
    Yes, but you should remember that Delphi's TComponent overrides the interface's reference counting, which often causes confusion. – Fabio Gomes Apr 02 '09 at 12:26
  • Using interfaces, the form would be freed when it goes out of scoop. I don't want that. I want it to live as long as it wants without any references to it, and then free it self when its done showing it self. – Vegar Apr 02 '09 at 20:29
  • Fabio: I'm sure you could override that. Vegar: Interfaces are reference counted, not scope-managed. – Arafangion Apr 02 '09 at 22:39
  • Yes, but as long as you don't keep a reference, wouldn't the referencecount go to zero when the code where you created the form goes out of scope? – Vegar Apr 03 '09 at 08:38
  • Only if you never pass it to something else... When you create the object, the ref gets incremented, so it is 1. When you assign it to something else, it becomes incremented again, so it is 2. When it leaves scope, it gets decremented, to ONE, and thus isn't destroyed. – Arafangion Apr 04 '09 at 04:30