Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to free dynamically created forms?

If I dynamically create a TForm using TForm.CreateNew(Application) to make a free-floating window do I have to keep track of these objects and free them upon Application close?

Or will delphi automatically free all forms on Application close?

Also, what happens if I have a free-floating dynamically created form and the user hits the close button? Do I need to call some code somewhere to free those?
If so, how? I assume I can't place it in any of the form's events.

like image 336
ycomp Avatar asked Dec 15 '22 18:12

ycomp


2 Answers

Just to touch on an important point not covered in the other answers...

Yes, when you create a form (or any other component) with an owner, it will be destroyed when the owner is destroyed.
But, very NB: This does not mean you won't have a leak. To clarify:

  • If every time you create a form you set Application as the owner, then the forms will be destroyed by the Application object when your app closes.
  • But (unless you code something extra), those forms will be destroyed only when the application closes.
  • In other words, if every time your user selects a particular menu item you create a particular form owned by the application, then more memory will be consumed over time. Depending how much memory is used each time you create the form, your application may run out of memory.

So, provided you don't keep re-creating the objects, the model is perfectly acceptable. However, this means that you do want to keep track of these objects. But not so you can free them yourself, rather so you can re-Show them instead of re-creating them.


Also to cover some of the other points in your question:

What happens if I have a free-floating dynamically created form window and the user hits the close button? Will do I need to call some code somewhere to free those?

You don't need to free them if next time your user shows the form you reuse the existing instance. If you're going to create a new instance, then you should free the form when it's closed. Otherwise all the old instances only get destroyed when your application closes.

How? I assume I can't place it in any of the form's events.

It just so happens that Delphi provides an ideal event: OnClose. If you hook that event, then you can set the var Action: TCloseAction to indicate what should happen when the form closes. By default:

  • An MDI form will be minimised (caMinimize).
  • And an SDI form will be hidden (caHide).

You can change this to destroy the form (caFree).

NOTE: If you do decide to destroy the form, be careful to not try reusing it after it has been destroyed. Any variable you had that pointed to the form will be pointing to the same location in memory, but the form is no longer there.

like image 177
Disillusioned Avatar answered Jan 05 '23 06:01

Disillusioned


Do I need to free dynamically created forms?

No you don't, except if you create the form with TForm.CreateNew(nil), that is passing no owner to the constructor.

The parameter for CreateNew is the owner, if the owner (Application/Form/WhatEverYouLike) gets deleted all owned objects will be freed. Give it a try.

procedure TMainfom.Button1Click(Sender: TObject);
var
 a:TForm;
begin
 With Tform.CreateNew(Application) do
   begin
   OnClose := MyAllFormClose;
   OnDestroy := AllMyFormDestroy;
   Show;
   end;
end;

procedure TMainfom.AllMyFormDestroy(Sender: TObject);
begin
   Showmessage(':( I''m going to be destroyed')
end;

procedure TMainfom.MyAllFormClose(Sender: TObject; var Action: TCloseAction);
begin
  // unremark if you want to get the form freed OnClose already 
  // Action := caFree;    
end;
like image 21
bummi Avatar answered Jan 05 '23 08:01

bummi