2016-11-16 36 views
3

当您在C++ Builder中的Vcl应用程序,它为你自动创建形式,并增加了线,如:C++ Builder:是否需要Application.CreateForm()?

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

我倾向于更喜欢使用new创建表单,所以删除所有这些行除了我的主要形式之外(参见this articleRob Kennedy进行了一些讨论)。

我最近发现的是,CreateForm()将非常高兴地创建包含纯虚方法的表单。在运行时会导致“纯虚函数称为”错误。相反,使用new创建表单给出了编译时“不能创建抽象类的实例”的错误。

编译时错误优于运行时错误,我不得不怀疑我是否可以在所有表​​单上使用new,包括主窗体?还有什么其他的东西是Application.CreateForm()在幕后做的,我可以复制这个?

+0

在项目 - >选项 - >表单中你有一个列表“自动创建表单”(和一个主表单选择)。您可以将除主窗体之外的所有窗体移动到“可用窗体”列表中,以在运行时手动创建它们。 – Flanker

回答

2

CreateForm()在Delphi中实现,并且Delphi很高兴地实例化了抽象类的对象(尽管为什么会有人猜测)。当跨越Delphi/C++边界时,任何一种语言提供的某种安全措施都可能会丢失。

在C++中,可以使用new所有次级形式,但你不能使用它的主要形式(没有一些麻烦)。

Application->CreateForm()第一次创建TForm对象时会分配Application->MainForm属性。 Application->Run()需要MainForm。如果未分配MainForm,则Run()将立即退出,终止该过程。

而且,MainForm属性在VCL中是只读的,所以不能手动设置它(可以在FireMonkey中)。

所以,这是不值得的麻烦试图通过new手动创建MainForm,因为你再有重复的一切,CreateForm()Run()做内部(建立应用程式和任务栏上的关系,并运行VCL消息循环) 。最好简单地确保你的主窗体类从不抽象开始,然后使用CreateForm()在运行时实例化它。让VCL做它的工作。

+0

我可以从TApplication派生出来,并使派生类中的MainForm读写吗?还是有更多的在CreateForm? –

+0

@NigelHawkins:不,你不能使'MainForm'属性读/写,因为'FMainForm'成员是私有的。但是有一些[一些技巧](http://stackoverflow.com/questions/25666626/)可以用来改变这个值。是的,在CreateForm()中还有更多的事情不只是设置属性。 –