I want to have a MainForm that is derived from a BaseForm that has a custom constructor. Since this is the Mainform, it is created by a call to Application.CreateForm(TMyMainForm, MyMainForm) in the *.dpr file. However, my custom constructor is not called during form creation.
Obviously, it works fine, if I call MyMainForm := TMyMainForm.Create(AOwner). Can I not use a form with custom constructor as the main form ?
TBaseForm = class(TForm)
constructor Create(AOwner:TComponent; AName:string);reintroduce;
end;
TMyMainForm = class(TBaseForm)
constructor Create(AOwner:TComponent);reintroduce;
end;
constructor TBaseForm.Create(AOwner:TComponent);
begin;
inherited Create(AOwner);
end;
constructor TMyMainForm.Create(AOwner:TComponent);
begin;
inherited Create(AOwner, 'Custom Constructor Parameter');
end;
In order for a form to become the VCL main form, it must be created via a call to
Application.CreateForm
. That in turn calls the virtual constructor declared inTComponent
. So, there's no way to get a different constructor to be called for the VCL main form.One option is that presented by Remy. To override the constructor declared in
TComponent
, and call a different constructor passing extra parameters. That can be a constructor in the same class, or an inherited constructor from a base class.Another option here would be to use abstract class methods on a base class. For instance,
In your derived classes you would override these abstract methods. Instead of setting properties in the constructor, code in the base form class could just call these methods. Of course, if you needed to do work in the constructor, you could perfectly well call these methods from the constructor.
Personally I have a prejudice against adding new constructors to classes that already have virtual constructors. The virtual constructor paradigm leads you towards using that single virtual constructor, and nothing else. If you start adding different constructors further down the hierarchy then it's just all too easy to end up with trouble caused by the wrong constructor being called when instantiating virtually.
Application.CreateForm()
cannot call areintroduce
'd constructor. When creating a new object, it calls theTComponent.Create()
constructor and expects polymorphism to call any derived constructors. Byreintroduce
'ing your custom constructor, you are not part of the polymorphic call chain.reintroduce
exposes a completely new method that simply has the same name as an inherited method but is not related to it.To do what you are attempting, don't use
reintroduce
for your constructors. Create a separate constructor in your Base form, and then have your MainFormoverride
the standard constructor and call your custom Base constructor, eg: