2012-09-22 180 views
7

我在Delphi XE工作来提供,Windows 7的能“未使用”班班德尔福XE

在一个应用程序,我想启用不同的报告类型为我的用户选择。 为此,我有1个基本报告类和每个报告类型的子类(xml,csv,ppt等)。

{Just an illustrating example} 
TBaseReport = class 
public 
    constructor Create; 
    procedure GenerateReport; virtual; abstract; 
    class function ReportType: string; virtual; abstract; 
end; 

T*Report = class(TBaseReport); 
//Etcetera. 

我想要做的就是使用Rtti来检测所有报告类并列出它们的ReportType。 之后,我想使用Rtti创建所选报告类的实例并调用GenerateReport。总而言之,这不难实现。

但是有一个主要的缺点:我从来没有对降序类的使用进行硬编码,所以代码没有包含在可执行文件中。

有没有一种体面的方式来强制链接器/编译器包含这些类?

解决办法是模拟报告在初始化部分的使用情况,但我宁愿不这样做。 更好的解决方案是使基类持久化并调用'RegisterClass(T * Report)';'在初始化部分。它有效,但我没有看到任何其他需要让它们持久存在,所以我再也不想这样做。另一方面,也许这是做到这一点的唯一方法?

在此先感谢。

回答

5

您可以使用{$STRONGLINKTYPES ON}编译器指令,在最终的exe文件中包含应用程序的所有符号,请记住,此选项会增加可执行文件的大小,因为可执行文件中包含的RTTI更多。

+0

这是做到这一点的方法。关于你的最后一点,没有更多的RTTI作为更多的代码 –

+0

我看到STRONGLINKTYPES的范围是全局的。你知道是否还有本地等价物? – deColaman

+0

刚刚为我的应用程序打开它以检查文件大小的增加。 exe从8.3MB增加到9.9MB。虽然这看起来很多,但好处超过我想的额外大小。 – deColaman

7

您可以创建您自己的RegisterClass版本。像RegisterReportClass。在内部,您可以保留自己的可以使用的报告类别列表。您的注册函数将采用TBaseReport类类型 - 不需要TPersistent。

您的RegisterReportClass方法应在初始化部分调用,确保包含类。

如果你看看图形单元,你可以看到TFileFormatsList = class(TList)。这是用于保存不同图形类型的类,可以用作创建自己的TReportFormatsList的示例。 Delphi使用静态函数TPicture.RegisterFileFormat将项目添加到其内部列表。

+0

虽然这确实是可能的,但它基本上是我在最后提到的总和。此外,它会否定我希望通过Rtti实现的动态部分。 – deColaman

+0

您仍然可以使用RTTI来处理类。但我不确定你为什么想这样做。如果每件事都有一个共同的基类,那么真的没有理由使用RTTI。你会用你的内部列表来找到这些类。添加新类时,在使用类列表的代码中不需要更改。对我来说,跟踪一个寄存器函数正在发生什么变得更简单,然后依赖于编译器指令。 –