Owner
Owner
is a property introduced in TComponent
, and Owner
itself has type TComponent
. The Owner
is used primarily to manage the lifetime of designed components. That is, components that you place on the form designer (or indeed other design surfaces) and whose lifetime is managed entirely by the framework. The documentation says:
Indicates the component that is responsible for streaming and freeing this component.
When a form is created, the streaming framework parses the .dfm file and instantiates the components that are listed within. These components are typically created with Owner
specified to be the form.
At the other end of a component's life is destruction. When a component is destroyed, it also destroys all of the components which it owns. Consider, for the sake of a concrete example, a TButton
that sits on a TForm
, placed there at design time. The streaming framework creates the button setting its Owner
to be the form. The form, as a descendent of TComponent
maintains a list of all the components that it owns. When the form is destroyed it walks over that list of owned components and destroys them. The button is destroyed in this manner.
There are many nuances to this:
- Components don't need to be owned by the form. For instance, components created at run time are owned by whatever component you pass to the constructor.
- Components need not have an owner, you can pass
nil
to the constructor. In this case, the programmer remains responsible for destroying the component.
- Ownership can be changed during the lifetime of a component.
Because the streaming framework instantiates components, the constructor of TComponent
is declared virtual:
constructor Create(AOwner: TComponent); virtual;
If you derived from a TComponent
descendent, and you wish for that derived component to be placed on a design surface, then you must respect this virtual constructor. If you define a constructor in your TComponent
descendent then it must override this virtual constructor.
It is worth pointing out that Win32 has a completely different concept of a window's owner, that should not be confused with the VCL concept of the same name. The Windows documentation says:
Owned Windows
An overlapped or pop-up window can be owned by another overlapped or
pop-up window. Being owned places several constraints on a window.
- An owned window is always above its owner in the z-order.
- The system automatically destroys an owned window when its owner is destroyed.
- An owned window is hidden when its owner is minimized.
Only an overlapped or pop-up window can be an owner window; a child
window cannot be an owner window.
In VCL terms, this concept is exposed by the PopupParent
property. That property was introduced after Delphi 7 so will not be available to you. In Delphi 7, the framework sets the window owner, and gives no easy mechanism to override the framework's choice. If you do need to influence window ownership then you must override CreateParams
and set Params.WndParent
. Unfortunately, there are a number of problems with the VCL handling of ownership in Delphi 7 and it is sometimes necessary to grub around in these somewhat gory details.
To show how easy it is to get confused, the VCL documentation says:
WndParent: The window handle of the parent window. This is the same as the Handle property of the parent control.
This is simply wrong. For a top-level window, this is the owner rather than the parent.
Parent
Parent
is a property defined in TControl
and has type TWinControl
. This property is used, broadly, to expose the Win32 concept of parent and child controls. The Windows documentation says:
A window can have a parent window. A window that has a parent is called a child window. The parent window provides the coordinate system used for positioning a child window. Having a parent window affects aspects of a window's appearance; for example, a child window is clipped so that no part of the child window can appear outside the borders of its parent window. A window that has no parent, or whose parent is the desktop window, is called a top-level window.
Essentially, the VCL Parent
property maps directly onto the Win32 parent concept.
Note however, that Parent
is defined in TControl
. Now, TControl
is not windowed, so a TControl
is not a child control in the Win32 sense, because a Win32 window's children are themselves windows. So, a TControl
with a defined Parent
is a child in the VCL sense, known as a non-windowed child control. These non-windowed controls paint themselves as part of their parent's paint handlers. The canonical example of such a control is TLabel
.
Note that when a windowed control, that is a TWinControl
descendent, is destroyed, it also destroys all of its children.
A TWinControl
descendent can enumerate its children using the ControlCount
and Controls[]
properties. These enumerate both windowed and non-windowed children.