delphicomponentstframe

Loaded procedure executed twice for TFrame's descendant


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?


Solution

  • This behavior is as-designed.

    Loaded

    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.