Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code not executed in TFrame.Create

I have created a component with TFrame as ancestor with the following code:

type
  TCHAdvFrame = class(TFrame)
  private
    { Private declarations }
    FOnShow : TNotifyEvent;
    FOnCreate : TNotifyEvent;
  protected
    procedure CMShowingChanged(var M: TMessage); message CM_SHOWINGCHANGED;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent) ; override;
  published
    property OnShow : TNotifyEvent read FOnShow write FOnShow;
    property OnCreate : TNotifyEvent read FOnCreate write FOnCreate;
  end;

implementation

{$R *.dfm}

{ TCHAdvFrame }

procedure TCHAdvFrame.CMShowingChanged(var M: TMessage);
begin
  inherited;
  if Assigned(OnShow) then
  begin
    ShowMessage('onShow');
    OnShow(self);
  end;
end;

constructor TCHAdvFrame.Create(AOwner: TComponent);
begin
  ShowMessage('OnCreate1');
  inherited ;
  ShowMessage('OnCreate2');
  if Assigned(OnCreate) then
  begin
    ShowMessage('OnCreate3');
    OnCreate(self);
  end;

I have registered the new component and did some tests. ShowMessage('OnCreate1'); and ShowMessage('OnCreate2'); are correctly executed but not ShowMessage('OnCreate3');

This prevents to add code during the implementation of a new instance of TCHAdvFrame.

Why is it and how can I solve this ?

like image 858
pio pio Avatar asked Sep 25 '14 21:09

pio pio


1 Answers

A frame is streamed in as part of its ultimate owner's constructor. Typically that will be a form. The form processes the .dfm file. It encounters new objects and creates them. Then it sets the properties of the newly created object. So, the frame's properties are set after its constructor returns.

This is the reason that TFrame does not have an OnCreate event. There is simply no way for the event to be fired because the event by necessity is assigned too late. The VCL designers omitted this event for the very same reason that led you to ask this question. So I do suspect that you likewise should not add this event.

How to solve this? Hard to say for sure unless we had a more detailed description of the problem. Perhaps you could override the frame's Loaded method to good effect. Or perhaps all you need to do is let consumers of your component override the constructor in their derived frames.

Related reading: http://delphi.about.com/od/delphitips2007/qt/tframe_oncreate.htm

like image 143
David Heffernan Avatar answered Sep 28 '22 05:09

David Heffernan