Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: When is the best time to instantiate a custom control at runtime?


This question is answered.


Permlink Replies: 19 - Last Post: Jun 5, 2017 11:57 AM Last Post By: Remy Lebeau (Te...
Enquiring Mind

Posts: 88
Registered: 10/6/08
When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 29, 2017 7:03 AM
Hi,

While still developing a custom control I like to instantiate it programmatically at runtime. In order to be able to do so the controls defined at design time need to have already been created and their properties loaded from the .dfm file. The most logical place to instantiate the custom control, I therefore thought, is in the Loaded method of the form, since this code is executed immediately after all the IDE-defined controls have been loaded from the .dfm file.

But when I do this, I get the following runtime error message:

Project Project1.exe raised exception class EInvalidOperation with message 'Cannot focus a disabled or invisible window'. Process stopped. Use Step or Run to continue.

To avoid the error I moved the custom control instantiation code into the OnShow event handler of the form. But this seems inelegant to me. It seems logically more coherent to create all controls in the same place, which is presumably in the Loaded procedure.

I take it that the form and all the controls it contains are still are disabled o invisible or both at the time the Loaded procedure runs. So I set the form's Enabled and Visible properties to True near the beginning of the Loaded procedure. The error still occurs when SetFocus is called. I then commented out SetFocus but the error persists. Can anyone suggest a way forward?

TIA,

EM
Jeremy North

Posts: 402
Registered: 9/20/99
Re: When is the best time to instantiate a custom control at runtime?
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 29, 2017 4:58 PM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring Mind wrote:
Hi,

While still developing a custom control I like to instantiate it programmatically at runtime. In order to be able to do so the controls defined at design time need to have already been created and their properties loaded from the .dfm file. The most logical place to instantiate the custom control, I therefore thought, is in the Loaded method of the form, since this code is executed immediately after all the IDE-defined controls have been loaded from the .dfm file.

But when I do this, I get the following runtime error message:

Project Project1.exe raised exception class EInvalidOperation with message 'Cannot focus a disabled or invisible window'. Process stopped. Use Step or Run to continue.

To avoid the error I moved the custom control instantiation code into the OnShow event handler of the form. But this seems inelegant to me. It seems logically more coherent to create all controls in the same place, which is presumably in the Loaded procedure.

I take it that the form and all the controls it contains are still are disabled o invisible or both at the time the Loaded procedure runs. So I set the form's Enabled and Visible properties to True near the beginning of the Loaded procedure. The error still occurs when SetFocus is called. I then commented out SetFocus but the error persists. Can anyone suggest a way forward?

Loaded is called during construction of the form. Just create your component in the constructor of the form (after inherited).

Creation events are:

Constructor - before inherited
Loaded
Constructor - after inherited
FormCreate
FormShow
FormActivate

sample code:

Memo and Timer on form. Timer interval set to 5000
private var FEvents: TStringList

constructor TForm2.Create(AOwner: TComponent);
begin
FEvents := TStringList.Create;
FEvents.Add('constructor before');
inherited;
FEvents.Add('constructor after');
end;

destructor TForm2.Destroy;
begin
FEvents.Free;
inherited;
end;

procedure TForm2.FormActivate(Sender: TObject);
begin
FEvents.Add('activate');
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
FEvents.Add('create');
end;

procedure TForm2.FormShow(Sender: TObject);
begin
FEvents.Add('show');
end;

procedure TForm2.Loaded;
begin
inherited;
FEvents.Add('loaded');
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
Memo1.Lines.Assign(FEvents);
end;

Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 30, 2017 2:54 AM   in response to: Jeremy North in response to: Jeremy North
Jeremy North wrote:

Loaded is called during construction of the form. Just create your component in the constructor of the form (after inherited).

Creation events are:

Constructor - before inherited
Loaded
Constructor - after inherited
FormCreate
FormShow
FormActivate

sample code:

Memo and Timer on form. Timer interval set to 5000
private var FEvents: TStringList

constructor TForm2.Create(AOwner: TComponent);
begin
FEvents := TStringList.Create;
FEvents.Add('constructor before');
inherited;
FEvents.Add('constructor after');
end;

destructor TForm2.Destroy;
begin
FEvents.Free;
inherited;
end;

procedure TForm2.FormActivate(Sender: TObject);
begin
FEvents.Add('activate');
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
FEvents.Add('create');
end;

procedure TForm2.FormShow(Sender: TObject);
begin
FEvents.Add('show');
end;

procedure TForm2.Loaded;
begin
inherited;
FEvents.Add('loaded');
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
Memo1.Lines.Assign(FEvents);
end;


Thanks you for the useful clarification of the sequence of events. The problem I encounter seems to be to do with the fact that the Create method of my custom control also assigns the control properties like Width and Height which it needs to get from controls loaded from the DFM file. The latter need to have been fully loaded before the my Create method can work properly.

I placed a breakpoint on the "inherited Loaded" statement at the beginning of the main form's Loaded method. Suppose that my custom control needs to be assigned some properties matching the properties of a streamed control Edit1. On the statement following the "inherited Loaded" statement I inspected the value of Edit1.ComponentState, expecting to find it cleared. But I was surprised to find that it was still [csLoading] even though the form's ComponentState value was []. Now since the form component owns the Edit1 component, one would expect it to clear the csLoading flag for all its child components (including Edit1) before it clears its own csLoading flag. In fact the Delphi documentation that I have states that:

"The csLoading flag indicates that a filer object is currently loading the component. The flag is set when the component is first created and not cleared until the component and all its children are fully loaded (when the Loaded method is called)."

Another possible contributory cause to the problem that I posted is that the MyControl.Create code includes some references to properties that might depend on ability of streamed controls referred to be enabled, e.g. properties relating to focus. I have therefore deleted these references.

Now on stepping out of the form's Loaded method in which my custom control is created an Access Violation error is thrown. This suggests that some of the properties, like Width and Height, which I thought had been assigned to it on the basis of the corresponding properties of Edit1, have not in fact been assigned, and the values are still zero.

EM
Roy Lambert

Posts: 1,063
Registered: 8/7/01
Re: When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 30, 2017 5:16 AM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring Mind

What would be really helpful here is some code, both for the component and what you're trying to do with it.

Roy Lambert

Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 31, 2017 4:03 AM   in response to: Roy Lambert in response to: Roy Lambert
Roy Lambert wrote:
Enquiring Mind

What would be really helpful here is some code, both for the component and what you're trying to do with it.

Roy Lambert


Alright, so here's some code:
type
  TCreateCustomControlsLocn= (clNil, clLoaded, clOnCreate, clOnShow); {Option for where procedure CreateCustomComponents is to be called}
 
const
  CCreateCustomControlsLocn= clOnShow;
 
type
  TFormMain = class(TForm)
    {snip}
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    {snip}
  private
    { Private declarations }
    FStreamUTF8Array: TStreamUTF8Array;   {Unicode streams to be displayed in list}
    {snip}
    FEditUnicodeCurrItem: TEditUnicode;         {Custom control generated from EditCurrItem as template} 
    {snip}
    FCustomControlsCreated: Boolean;
    procedure CreateCustomControls;  {Creates custom controls at run time}
    procedure Loaded; override;
    {snip}
  public
    { Public declarations }
  end;
 
procedure TFormMain.CreateCustomControls;
 
  procedure CreateTEditUnicodeControl(Edit: TEdit; ControlName: string;
      var EditUnicode: TEditUnicode);
  var
    OwnsStreamUTF8: Boolean;
  begin
    OwnsStreamUTF8:= True;
   {Create TEditUnicode control using Edit as template, then delete Edit}
    EditUnicode:= TEditUnicode.CreateInPlaceOf(Edit, OwnsStreamUTF8);
    EditUnicode.Name:= ControlName;
  end;
 
  begin
    if not FCustomControlsCreated then
    begin
      {Create FEditUnicodeCurrItem in place of EditCurrItem:}
      CreateTEditUnicodeControl(EditCurrItem, 'FEditUnicodeCurrItem', FEditUnicodeCurrItem);
      {snip}
      FCustomControlsCreated:= True;
    end;
end;
 
procedure TFormMain.Loaded;
begin
  inherited Loaded;
  if (CCreateCustomControlsLocn= clLoaded) and not FCustomControlsCreated then
    begin
      CreateCustomControls;
      FCustomControlsCreated:= True;
    end;
end;
 
 
procedure TFormMain.FormShow(Sender: TObject);
begin
  if (CCreateCustomControlsLocn= clOnShow) and not FCustomControlsCreated then
    begin
      CreateCustomControls;
      FCustomControlsCreated:= True;
    end;
  DataToControls;
  FEditUnicodeCurrItem.SetFocus;
end;
 
procedure TFormMain.FormCreate(Sender: TObject);
var
  i: integer;
  StreamUTF8I: TStreamUTF8;
begin
  SetLength(FStreamUTF8Array, 10);
  for i:= 0 to 9 do
    begin
      StreamUTF8I:= TStreamUTF8.Create;
      FStreamUTF8Array[i]:= StreamUTF8I;
    end;
  {snip}
  if (CCreateCustomControlsLocn= clOnCreate) and not FCustomControlsCreated then
    begin
      CreateCustomControls;
      FCustomControlsCreated:= True;
      DataToControls;
    end;
end;
 
{In another unit:}
constructor TEditUnicode.CreateInPlaceOf(Source: TEdit; OwnsStreamUTF8: Boolean);
begin
  Create(Source.Owner, OwnsStreamUTF8);
  Parent:= Source.Parent;
  Name:= AnsiReplaceStr(Source.Name, 'Edit', 'EditUnicode');
  TextAsWidestring:= Source.Text;
  {Set position:}
  BoundsRect:= Source.BoundsRect;
  {Set key properties:}
  Anchors:= Source.Anchors;
  Font.Assign(Source.Font);
  Color:= Source.Color;
  Align:= Source.Align;
  ShowHint:= Source.ShowHint;
  TabOrder:= Source.TabOrder;
  TabStop:= Source.TabStop;
  {Assign Canvas properties (N.B. Source does not expose a Canvas)}
  FCanvasUnicode.Font.Assign(Font);
  FCanvasUnicode.Brush.Color:= Color;
  FCanvasUnicode.Pen.Color:= clBlack;
  {Remove Source from child controls of its parent:}
  Source.Parent.RemoveControl(Source);
  {Remove Source from components owned by its owner}
  Source.Owner.RemoveComponent(Source);
  {Free source (in case this was not already done by RemoveComponent)}
  Source.Free;
  FCharHeight:= FCanvasUnicode.TextHeight('M');
end;
 


Since my previous post I have discovered that the code works when CreateCustomControls is called from the OnCreate or the onShow event handlers, but not when called from Loaded. In the latter case, an access violation error is thrown when one steps out of the Loaded procedure but before the execution has reached the OnShow event handler.

Regards,
EM

Edited by: Enquiring Mind on May 31, 2017 12:09 PM

Edited by: Enquiring Mind on May 31, 2017 8:02 PM
Roy Lambert

Posts: 1,063
Registered: 8/7/01
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 31, 2017 5:09 AM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring Mind

I'm guessing but I'd suggest start with tracing into

constructor TEditUnicode.CreateInPlaceOf(Source: TEdit; OwnsStreamUTF8: Boolean);

Looking online I suspect its something to do with this

<<Applications should not call RemoveControl directly. Child controls are automatically inserted and removed when added or deleted at design time. At runtime, use the Parent property of the child control to remove it from the Controls array. >>

Try just setting Parent to nil, or better still just Free the component that should remove it from the controls array.

I must say I'm confused as to just what you're trying to do.

Roy Lambert

Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 31, 2017 6:16 AM   in response to: Roy Lambert in response to: Roy Lambert
Roy Lambert wrote:
Enquiring Mind

I'm guessing but I'd suggest start with tracing into

constructor TEditUnicode.CreateInPlaceOf(Source: TEdit; OwnsStreamUTF8: Boolean);

Looking online I suspect its something to do with this

<<Applications should not call RemoveControl directly. Child controls are automatically inserted and removed when added or deleted at design time. At runtime, use the Parent property of the child control to remove it from the Controls array. >>

Try just setting Parent to nil, or better still just Free the component that should remove it from the controls array.

I must say I'm confused as to just what you're trying to do.

Roy Lambert


Roy,

Thanks for pointing out that RemoveControl should need not be called directly as it is called automatically when the control is freed. After deleting the calls to RemoveControl and RemoveComponent I find that the form continues to behave as before in all respects.

For the time being I will set aside investigating the cause of the AV exception when the custom controls are created from the Loaded method, because when stepping in the debugger on from the end of the Loaded method the exception is thrown before the next source code line is reached. To see where the exception is thrown one has to enter the CPU window, at which point the code corresponds to VCL code and is therefore difficult to understand.

It's so long from the previous time that I posted any code in this newsgroup that I have forgotten the exact tags needed to format code. I thought that they were <code> ... <code> but they aren't. Can you remind me what they are?

As for what I am seeking to achieve, it's to replace at runtime some standard VCL controls acting as placeholders with some custom controls (which are not yet installed into the IDE). So the custom controls have to be created, then assigned any properties that correspond to placeholder properties, and finally the placeholder controls have to be deleted.

TIA,
EM
Roy Lambert

Posts: 1,063
Registered: 8/7/01
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 31, 2017 7:47 AM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring Mind


For the time being I will set aside investigating the cause of the AV exception when the custom controls are created from the Loaded method, because when stepping in the debugger on from the end of the Loaded method the exception is thrown before the next source code line is reached. To see where the exception is thrown one has to enter the CPU window, at which point the code corresponds to VCL code and is therefore difficult to understand.

I think you may need to have the debug dcus engaged, or if debugging is disabled in a unit have it enabled. I've often found that it looks as though its one line but its actually in a unit that the debugger doesn't step into.

It's so long from the previous time that I posted any code in this newsgroup that I have forgotten the exact tags needed to format code. I thought that they were <code> ... <code> but they aren't. Can you remind me what they are?

I'm the same

As for what I am seeking to achieve, it's to replace at runtime some standard VCL controls acting as placeholders with some custom controls (which are not yet installed into the IDE). So the custom controls have to be created, then assigned any properties that correspond to placeholder properties, and finally the placeholder controls have to be deleted.

That's why I can't understand it. Why not just install them in the IDE and drop them on the form? You seem to be creating pain for yourself :(

Roy

Lajos Juhasz

Posts: 801
Registered: 3/14/14
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 31, 2017 8:01 AM   in response to: Roy Lambert in response to: Roy Lambert
Roy Lambert wrote:

That's why I can't understand it. Why not just install them in the
IDE and drop them on the form? You seem to be creating pain for
yourself :(

Instead of using placeholders you could after creating the control
position it with SetBounds, for me that is easier than using
placeholders.
Roy Lambert

Posts: 1,063
Registered: 8/7/01
Re: When is the best time to instantiate a custom control at runtime? [Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 31, 2017 8:13 AM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring Mind

I think I'm begining to see what's happening - in the earlier event (Loaded) you're trying to free a control that hasn't come fully into existence. Try setting the visble property of teh controls you drop on the form as placeholder to false in the IDE. You can then basically use them as you are to get properties from but totally ignore them otherwise since they'll never be seen.

Roy Lambert

Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 1, 2017 8:48 AM   in response to: Roy Lambert in response to: Roy Lambert
Roy Lambert wrote:
Enquiring Mind

I think I'm begining to see what's happening - in the earlier event (Loaded) you're trying to free a control that hasn't come fully into existence. Try setting the visble property of teh controls you drop on the form as placeholder to false in the IDE. You can then basically use them as you are to get properties from but totally ignore them otherwise since they'll never be seen.

Roy Lambert


Roy,

You have put your finger on the problem. If I one doesn't release of the placeholder control in the constructor TEditUnicode.CreateInPlaceOf then a runtime error is no longer thrown when the Loaded method is exited. On the downside one is left with all the placeholder controls in memory. They can either be destroyed later (e.g. in the OcCreate event handler) or may be left to languish in the background thereby bloating the program memory and increasing the number of components and controls in the application and corresponding Windows handles.

EM
Roy Lambert

Posts: 1,063
Registered: 8/7/01
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 2, 2017 12:42 AM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring

On the downside one is left with all the placeholder controls in memory.

Much as I dislike code bloat this is going to be miniscule in terms of current PC's RAM

What I'm still struggling to understand is why you're doing it this way to start with. Why not add the control to the IDE and just drop what you ultimately want on the form?

Roy Lambert
Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 2, 2017 12:29 PM   in response to: Roy Lambert in response to: Roy Lambert
Roy Lambert wrote:
Enquiring

On the downside one is left with all the placeholder controls in memory.

Much as I dislike code bloat this is going to be miniscule in terms of current PC's RAM

What I'm still struggling to understand is why you're doing it this way to start with. Why not add the control to the IDE and just drop what you ultimately want on the form?

Roy Lambert

Because during development of the control it is more productive not to have to re-install the compiled code in a package and the IDE every time it is recompiled.

EM
Roy Lambert

Posts: 1,063
Registered: 8/7/01
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 2, 2017 11:06 PM   in response to: Enquiring Mind in response to: Enquiring Mind
EM

Because during development of the control it is more productive not to have to re-install the compiled code in a package and the IDE every time it is recompiled.

Sorry if I'm teaching granny to suck eggs but it sounds as though you're not following current practice.

Components should be split into two parts - design time and run time. The design time contains the interactions with the IDE and the run time the code that does the job when the application is up and running. Unless you're changing the design time stuff there's no need to re-install the component in a package. Most of the time there's no need for a full build of an application using the component either.

I have quite a few homebrew components. The only time I have to recompile the packages is when I add new published properties or when a 3rd party component that is relied on changes its package name so my package can no longer find it when the IDE is started.

New methods will (I think but its a while since I did any) require a build rather than a compile.


Roy Lambert

Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: When is the best time to instantiate a custom control at runtime? [Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 31, 2017 11:37 AM   in response to: Enquiring Mind in response to: Enquiring Mind
El 31/05/2017 a las 15:16, Enquiring Mind escribió:
It's so long from the previous time that I posted any code in this newsgroup that I have forgotten the exact tags needed to format code. I thought that they were <code> ... <code> but they aren't. Can you remind me what they are?

You must enclose the word code between curly braces {}
Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 1, 2017 3:23 AM   in response to: Antonio Estevez in response to: Antonio Estevez
Antonio Estevez wrote:
El 31/05/2017 a las 15:16, Enquiring Mind escribió:
It's so long from the previous time that I posted any code in this newsgroup that I have forgotten the exact tags needed to format code. I thought that they were <code> ... <code> but they aren't. Can you remind me what they are?

You must enclose the word code between curly braces {}

Thanks!
Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 1, 2017 8:35 AM   in response to: Jeremy North in response to: Jeremy North
Jeremy North wrote:


Loaded is called during construction of the form. Just create your component in the constructor of the form (after inherited).

I am not quite sure why I didn't take heed of this advice straight away. I suppose I was bent on finding out why there was a problem with calling the constructor of the custom component from within the Loaded method. After investigating several options I have concluded that calling it in the overridden constructor of the form after inherited is the best option. For some reason I was labouring under the misapprehension that the DFM properties would not have been loaded in the Create method, and that putting the custom component constructor in Create could affect when the OnCreate event is dispatched. In fact I presumed that OnCreate would be dispatched in the inherited Create call, but I have discovered that it is actually called at the end of Create after the custom code added after inherited. So with reference to the code that I posted in another post, I have found that the following option works, and is preferable to locating the CreateCustomControls call in the OnCreate or OnShow event handlers:

TFormMain= class(TForm)
public
   constructor Create(AOwner: TComponent); override;
end;
 
constructor TFormMain.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  if CCreateCustomControlsLocn= clCreate then
    CreateCustomControls;
  {OnFormCreate seems to be called here}
end;


With the above code the sequence of events turns out to be:
1. Create, begin
2. inherited Create
3. Loaded
4. CreateCustomControls
5. FormCreate event handler
6. Create, end
6. FormShow event handler

So thank you for giving the best answer.
EM

Creation events are:

Constructor - before inherited
Loaded
Constructor - after inherited
FormCreate
FormShow
FormActivate

sample code:

Memo and Timer on form. Timer interval set to 5000
private var FEvents: TStringList

constructor TForm2.Create(AOwner: TComponent);
begin
FEvents := TStringList.Create;
FEvents.Add('constructor before');
inherited;
FEvents.Add('constructor after');
end;

destructor TForm2.Destroy;
begin
FEvents.Free;
inherited;
end;

procedure TForm2.FormActivate(Sender: TObject);
begin
FEvents.Add('activate');
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
FEvents.Add('create');
end;

procedure TForm2.FormShow(Sender: TObject);
begin
FEvents.Add('show');
end;

procedure TForm2.Loaded;
begin
inherited;
FEvents.Add('loaded');
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
Memo1.Lines.Assign(FEvents);
end;

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 1, 2017 10:14 AM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring Mind wrote:

After investigating several options I have concluded that calling it
in the overridden constructor of the form after inherited is the best
option.

In the overriden constructor, or in the OnCreate event, either will
work.

For some reason I was labouring under the misapprehension that the DFM
properties would not have been loaded in the Create method, and that
putting the custom component constructor in Create could affect when
the OnCreate event is dispatched.

No. However, the timing of the OnCreate event is affected by the
Form's OldCreateOrder property. When false (the default), OnCreate is
fired in the form's AfterConstruction() method after all Form
constructors, inherited and overriden, have been called first. When
true, OnCreate is fired in the inherited base constructor. Either way,
OnCreate is fired after DFM streaming has finished.

In fact I presumed that OnCreate would be dispatched in the inherited
Create call

Only if OldCreateOrder is true.

but I have discovered that it is actually called at the end of Create
after the custom code added after inherited.

More accurately, it it called by Afterconstruction() after your
overriden constructor exits.

--
Remy Lebeau (TeamB)
Enquiring Mind

Posts: 88
Registered: 10/6/08
Re: When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 2, 2017 12:27 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

In the overriden constructor, or in the OnCreate event, either will
work.
Creating the custom controls in a virtual method has the advantage over doing the same in an event handler is that the virtual method can be overridden in a descendent form to extend or otherwise modify it.

For some reason I was labouring under the misapprehension that the DFM
properties would not have been loaded in the Create method, and that
putting the custom component constructor in Create could affect when
the OnCreate event is dispatched.

No. However, the timing of the OnCreate event is affected by the
Form's OldCreateOrder property. When false (the default), OnCreate is
fired in the form's AfterConstruction() method after all Form
constructors, inherited and overriden, have been called first. When
true, OnCreate is fired in the inherited base constructor. Either way,
OnCreate is fired after DFM streaming has finished.
Is there a similar facility for all control classes whereby the event is dispatched not in the inherited method chain but at the exit of final method in the chain?

In fact I presumed that OnCreate would be dispatched in the inherited
Create call

Only if OldCreateOrder is true.

but I have discovered that it is actually called at the end of Create
after the custom code added after inherited.

More accurately, it it called by Afterconstruction() after your
overriden constructor exits.

Thank you for these useful insights. They explain why constructing the custom controls in the Create constructor works satisfactorily.

EM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: When is the best time to instantiate a custom control at runtime?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 5, 2017 11:57 AM   in response to: Enquiring Mind in response to: Enquiring Mind
Enquiring Mind wrote:

Is there a similar facility for all control classes whereby the event
is dispatched not in the inherited method chain but at the exit of
final method in the chain?

No.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02