Do I need to create dynamically generated forms?

If I dynamically create a TForm using TForm.CreateNew (Application) to create a free floating window, do I need to keep track of these objects and free them when the application is closed?

Or will delphi automatically release all forms on Application close?

Also, what happens if I have a freely floating dynamically generated form and the user clicks the close button? Do I need to call some code somewhere to free them?
If so, how? I am guessing I cannot put it on any events of the form.

+3


source to share


4 answers


Do I need to free dynamically generated forms?

No, you don't, unless you create a form with TForm.CreateNew(nil)

that doesn't pass any owner to the constructor.



The parameter CreateNew

is owned, if the owner (Application / Form / WhatEverYouLike) is removed, all objects owned by it will be freed. Try it.

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;

      

+2


source


Just touch on an important point not touched upon by 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 important: This does not mean that there will be no leak. To clarify:

  • If every time you create a form, you set Application

    as owner, then the forms will be destroyed by the object Application

    when your application closes.
  • But (if you haven't baked something extra), these forms will only be destroyed when the application is closed.
  • In other words, if every time your user selects a specific menu item, you create a specific form that belongs to the application, then more memory will be consumed over time. Depending on how much memory is used each time you create the form, your application might not work.

So, if you don't keep recreating objects, the model is fine. However, this means that you want to track these objects. But not so, you can free them yourself, you can restore them instead instead of re-creating them.


Also consider some other questions in your question:

What happens if I have a freely floating dynamically created form window and the user clicks the close button? Will I need to call the code somewhere to free them?



You don't need to free them the next time your user shows the form you are reusing an existing instance. If you are going to create a new instance, you must release the form when it is closed. Otherwise, all old instances are destroyed only when the application is closed.

How? I am guessing I cannot put it on any events of the form.

It so happened that Delphi provides the perfect event: OnClose

. If you hook up this event, you can set var Action: TCloseAction

to specify what should happen when the form is closed. Default:

  • The MDI form will be minimized ( caMinimize

    ).
  • And the SDI form will be hidden ( caHide

    ).

You can change this to destroy the shape ( caFree

).

NOTE . If you choose to destroy a form, be careful not to reuse it after it is destroyed. Any variable specified in the form will point to the same location in memory, but the form no longer exists.

+4


source


The parameter you passed CreateNew

is the owner of the component. When the owner of a component is destroyed, it destroys all the components it owns. Thus, the application object is the owner of your form. When the application is closed, the application object is destroyed. And so it destroys all the components it owns. Including your dynamically generated form.

+2


source


I don't know why people think that forms are some kind of magical entity that has its own unique behavior and rules.

Forms are normal objects derived from TForm and TCustomForm, which are ultimately derived from TObject like any other class in Delphi.

If you create something that derives from TObject dynamically, it is destroyed when the application exits. However, if you cannot destroy it yourself and leave it on the system, that is usually considered a "memory leak". This is not very important for programs that start once and finish quickly. But for things that users leave open for hours or days in a row, memory leaks can get pretty annoying.

As mentioned earlier, TForms has an OnClose event that has an Action parameter. You can set the Action to caFree and the form will be destroyed when returned to the call to Show or ShowModal that displayed it. But if you use it, you need to create the form object yourself, and not use the default auto-creation mechanism.

Other types of objects don't have one like TStringList. You just need to practice "safe object management" and ensure that the objects you create are also destroyed in a timely manner, including forms. This could fall into a whole rat nest of discussions about garbage collection-related stuff, interfaces, and a lot of related stuff. Suffice it to say that you need to be aware of the options and manage the object's lifetime appropriately, rather than just leaving them destroyed when the application exits.

+2


source







All Articles