Search code examples
delphidelphi-7tform

RegisterClass X Extended TForm/EFilerError 'A class named TForm already exists'‏


I have extended the TForm in a separate unit...

TForm = class(Forms.TForm)
protected
{ convenient extensions }
public
{ more extensions }
end;

And this unit (with the extended TForm) is declared in all units of the Forms to which I want to apply these extensions...

However, in some of these units have the following code snippets:

Initialization
  RegisterClass(TFormN);

Finalization
  UnRegisterClass(TFormN);

But this way I get the message [EFilerError] 'A class named TForm already exists'

I spent the last few days looking for a way to solve / work around this conflict, but without success ...

Has anyone experienced this ...? Or can shed light on why this problem ...?


The problem is that I already have implemented this unit, with the extended form, in 2 projects - successfully...

Just now, in the third project, the form classes are called without being instanciated... and I can't change the extended class form from:

TForm = class(Forms.TForm)

to:

TStyleForm = class(Forms.TForm)

...


What I'd need is something like:

TFormStyle = class(Forms.TForm)
public
  constructor Create(AOwner: TComponent); override;
end;

TForm = ^TFormStyle;

But in the units I can't do a declaration like:

TMyForm = class(TForm)
  { something... } 
end;

Cause now it's a pointer...


Solution

  • You now have two distinct types in your program, both with the name TForm. The one declared in the VCL is registered with the name TForm. Since you are trying to register your TForm with the global registry, using the same name as the VCL version, the registration naturally fails.

    Some possible ways forward:

    1. Rename your form to avoid the clash.
    2. Don't register your class at all. You don't need to register forms since they are not instantiated by the streaming framework. You instantiate them by providing a meta class. Either to Application.CreateForm, or by a standard constructor TForm.Create. You'd need to make sure that you always listed the unit that declared your TForm after Forms in any uses clauses. Or use a fully scoped type like MyForms.TForm.
    3. If you used a later version of Delphi you could add your extensions using a class helper.

    Personally I'd be inclined to do both 1 and 2 above.

    Note that I am assuming that your intent is that your TForm is used for all your forms rather than Forms.TForm.