4

When you create a Vcl application in C++Builder, it auto-creates forms for you and adds lines like:

Application->CreateForm(__classid(Tmain), &main);

I tend to prefer to use new to create forms, so remove all of these lines except the one for my main form (see this article by Rob Kennedy for some discussion).

What I have discovered recently is that CreateForm() will quite happily create forms that contain pure virtual methods. Which can lead to "pure virtual function called" errors at run-time. In contrast, creating the form using new gives a compile-time "cannot create instance of abstract class" error.

Compile-time errors being preferable to run-time errors, I have to wonder whether I can use new on all forms, including the main form? What other stuff is Application.CreateForm() doing behind the scenes and can I duplicate this?

Community
  • 1
  • 1
Nigel Hawkins
  • 824
  • 1
  • 8
  • 23
  • Under Project->Options->Forms you have a list "Auto-create forms" (and a main form selection). You can move all forms except main one to "Available forms" list, to manually create them at run-time. – Flanker Nov 20 '16 at 05:08

1 Answers1

3

CreateForm() is implemented in Delphi, and Delphi happily instantiates objects of abstract classes (why is anyone's guess, though). When crossing over the Delphi/C++ boundary, certain safeguards provided by either language on its own can be lost.

In C++, you can use new for all secondary Forms, but you cannot use it for the main form (without some hassles).

Application->CreateForm() assigns the Application->MainForm property when creating a TForm object for the first time. The MainForm is required by Application->Run(). If the MainForm is not assigned, Run() will exit immediately, terminating the process.

Also, the MainForm property is read-only in VCL, so you cannot set it manually (you can in FireMonkey, though).

So, it is not worth the hassle trying to create the MainForm manually via new, as you then have to duplicate everything that CreateForm() and Run() do internally (establish the app's relationship with the taskbar, and run the VCL message loop). It is best to simply make sure your main form class is never abstract to begin with, and then use CreateForm() to instantiate it at runtime. Let the VCL do its work.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Could I derive from TApplication and make MainForm read-write in the derived class? Or is there more going on in CreateForm? – Nigel Hawkins Nov 18 '16 at 12:19
  • @NigelHawkins: no, you cannot make the`MainForm` property read/write, as the `FMainForm` member is private. But there are [some tricks](http://stackoverflow.com/questions/25666626/) you can use to alter the value anyway. And yes, there is more going on in `CreateForm()` than just setting the property. – Remy Lebeau Nov 18 '16 at 17:51