I've registered as component a TFrame
's descendant class and I've noticed that the Loaded
procedure is executed twice:
Runtime:
TMyFrame = class(TFrame)
private
protected
procedure Loaded(); override;
public
constructor Create(AOwner : TComponent); override;
end;
constructor TMyFrame.Create(AOwner : TComponent);
begin
ShowMessage('Before TMyFrame.Create');
inherited Create(AOwner);
ShowMessage('After TMyFrame.Create');
end;
procedure TMyFrame.Loaded();
begin
ShowMessage('Before TMyFrame.Loaded');
inherited;
ShowMessage('After TMyFrame.Loaded');
end;
Designtime:
procedure Register;
begin
RegisterComponents('Test', [TMyFrame]);
end;
Output:
At runtime, on creating a form in which there is a TMyFrame
component.
Before TMyFrame.Create
Before TMyFrame.Loaded
After TMyFrame.Loaded
After TMyFrame.Create
Before TMyFrame.Loaded
After TMyFrame.Loaded
At designtime, on adding a TMyFrame
to a form:
Before TMyFrame.Create
Before TMyFrame.Loaded
After TMyFrame.Loaded
After TMyFrame.Create
At designtime, opening a form in which there is a TMyFrame
component:
Before TMyFrame.Create
Before TMyFrame.Loaded
After TMyFrame.Loaded
After TMyFrame.Create
Before TMyFrame.Loaded
After TMyFrame.Loaded
Why the Loaded
procedure is executed twice? How to avoid this?
This behavior is as-designed.
Loaded may be called multiple times on inherited forms. It is called every time a level of inheritance is streamed in. Do not allocate memory in an overridden Loaded method without first checking that the memory has not been allocated in a previous call.