Posted by webmaster Guido
In Reply to Create Delphi form dynamically posted by
Johan
: When I create a Delphi form dynamically, the constructor "Create" expects an "Owner" parameter.
: When should I specify "nil", "self" or "Application", and why?
When creating a Delphi component dynamically (a form or whatever other component), in the Create method
you have to specify its owner, for example:
Form2 := TForm2.Create(aOwner);
aOwner can be another object or nil (no owner):
- a component with an owner is destroyed automatically, when its owner is destroyed.
- a component without an owner (you passed nil as the owner) will not be destroyed automatically,
so you must destroy (free) it yourself. Failing to do so leads to what is called "memory leaks",
that eventually could "hang" your
program or even need a reboot of Windows.
Here are a few practical rules:
- If you dynamically create Form2 in the code of your main form Form1, and you want Form2 to be
destroyed automatically at the end of the program, then pass Application
as the owner.
- If you create Form3 in the code of another form Form2 (not the main form), and you want Form3
to be destroyed automatically when Form2 is destroyed, then pass self as
the owner. The variable self in this case points to Form2.
- If you dynamically create a form (or any other component) and for some reason you want to explicitly
free it sometime later, always pass nil as its owner. Otherwise, you run
the risk that the component
is "freed" twice, giving errors that are very difficult to debug.
Now, for some code examples.
1. Owner is another form
var
Form2: TForm2;
procedure TForm1...
begin
...
Form2 := TForm2.Create(Form1);
Form2 will be destroyed automatically when Form1 is destroyed. DO NOT "Free" Form2 yourself !
Instead of TForm2.Create(Form1) you will usually see:
var
Form2: TForm2;
procedure TForm1.SomeProcedure;
begin
...
Form2 := TForm2.Create(self);
The variable self is the object of which SomeProcedure is a method. That's a complicated
way of saying: in our example, self is the same as Form1. Thus, the two code examples above
are equivalent.
2. Owner is the global variable Application
var
Form2: TForm2;
procedure TForm1...
begin
...
Form2 := TForm2.Create(Application);
Here, Form2 will be destroyed automatically when the Application is
destroyed, that is: when the program stops.
3. Owner is nil
procedure TForm1.SomeProcedure;
var
FDialog: TForm2;
begin
FDialog := TForm2.Create(nil);
FDialog.ShowModal;
...
FDialog.Free;
In this case, the form FDialog does not have an owner, so you have to destroy FDialog yourself from
the moment that it's not needed anymore.
Guido, DelphiLand Team
|