【问题标题】:C++Builder: Is Application.CreateForm() necessary?C++Builder:Application.CreateForm() 是必要的吗?
【发布时间】:2017-03-30 14:11:55
【问题描述】:

当您在 C++Builder 中创建 Vcl 应用程序时,它会自动为您创建表单并添加如下行:

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

我更喜欢使用new 创建表单,因此删除所有这些行,除了我的主要表单行(请参阅Rob Kennedythis article 进行一些讨论)。

我最近发现的是 CreateForm() 将非常乐意创建包含纯虚方法的表单。这可能会在运行时导致“纯虚函数调用”错误。相反,使用new 创建表单会产生编译时“无法创建抽象类的实例”错误。

编译时错误优于运行时错误,我想知道是否可以在所有表​​单(包括主表单)上使用newApplication.CreateForm() 在幕后做了什么其他的事情,我可以复制一下吗?

【问题讨论】:

  • 在 Project->Options->Forms 下,您有一个“自动创建表单”列表(以及一个主表单选择)。您可以将除主表单之外的所有表单移动到“可用表单”列表中,以便在运行时手动创建它们。

标签: c++builder vcl c++builder-xe6


【解决方案1】:

CreateForm() 是在 Delphi 中实现的,并且 Delphi 愉快地实例化了抽象类的对象(为什么有人猜测)。当跨越 Delphi/C++ 边界时,任何一种语言本身提供的某些保护措施都可能会丢失。

在 C++ 中,您可以将new 用于所有次要表单,但您不能将它用于主要表单(没有一些麻烦)。

Application->CreateForm() 在第一次创建TForm 对象时分配Application->MainForm 属性。 MainForm 需要 Application->Run()。如果MainForm没有赋值,Run()会立即退出,终止进程。

另外,MainForm 属性在 VCL 中是只读的,因此您不能手动设置它(不过,您可以在 FireMonkey 中)。

因此,尝试通过new 手动创建MainForm 是不值得的,因为您必须复制CreateForm()Run() 在内部执行的所有操作(建立应用程序与任务栏的关系,并运行 VCL 消息循环)。最好简单地确保您的主表单类一开始就不是抽象的,然后在运行时使用CreateForm() 来实例化它。让 VCL 完成它的工作。

【讨论】:

  • 我可以从 TApplication 派生并在派生类中使 MainForm 读写吗?还是在 CreateForm 中发生了更多事情?
  • @NigelHawkins:不,您不能使MainForm 属性读/写,因为FMainForm 成员是私有的。但是有some tricks 可以用来改变值。是的,CreateForm() 不仅仅是设置属性。
猜你喜欢
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多