Delphi 基于条件定义包含不同的表单(.dfm)文件

Delphi 基于条件定义包含不同的表单(.dfm)文件,delphi,delphi-7,dfm,Delphi,Delphi 7,Dfm,我们为两个略有不同的机器版本生产两个版本的软件。这两台机器上使用的硬件完全不同,因此我们维护两个项目:Project1和Project2。一些代码(.pas和.dfm,视情况而定)在两个项目之间共享,但大多数代码目前是Project1或Project2独有的 Project2最初是从Project1中克隆出来的,目的是让新机器启动并运行,但现在我正在重新构造代码,以便使两个项目之间的表单和单元变得通用,从而减少开发工作量。如{$IFDEF PROJ1}中所述,条件定义在需要时使用 除了项目1中的

我们为两个略有不同的机器版本生产两个版本的软件。这两台机器上使用的硬件完全不同,因此我们维护两个项目:Project1和Project2。一些代码(.pas和.dfm,视情况而定)在两个项目之间共享,但大多数代码目前是Project1或Project2独有的

Project2最初是从Project1中克隆出来的,目的是让新机器启动并运行,但现在我正在重新构造代码,以便使两个项目之间的表单和单元变得通用,从而减少开发工作量。如
{$IFDEF PROJ1}
中所述,条件定义在需要时使用

除了项目1中的一个复选框(而不是项目2中的一个)之外,我们有一个项目之间几乎相同的表单。让我们用单位文件Masking.pas(和Masking.dfm)调用此表单
Masking

步骤:

  • 将.pas和.dfm从Project1移动到公共共享文件夹中
  • 将Masking.dfm重命名为MaskingProj1.dfm
  • 将Masking.dfm从Project2复制到公共共享文件夹中,并重命名为MaskingProj2.dfm
  • 手动编辑每个项目的项目(.dpr)文件以反映更改
  • 在Masking.pas中,将
    {$R*.dfm}
    更改为:

    {$IFDEF PROJECT1}
    {$R MaskingProj1.dfm}
    {$ELSE}
    {$R MaskingProj2.dfm}
    {$ENDIF}

  • 同样在Masking.pas中,使用
    {$IFDEF PROJECT1}
    条件定义编译出TCheckBox控件和Project2的相关代码

最后,重新打开这两个项目并重新编译。嘿,普雷斯托!它起作用了。现在Project1使用Masking.pas和MaskingProj1.dfm。Project2使用Masking.pas和MaskingProj2.dfm

这一切似乎都很好…除了当我尝试在IDE中查看表单时,通过在表单和单元(F12)之间切换,什么都不显示。我可以手动编辑任何一个.dfm文件,并且在重新编译后,更改会反映在应用程序中……但是IDE不会显示表单


我做错了什么?根据条件定义,是否可以通过这种方式更改
{$R*.dfm}
以使.pas文件使用不同的表单文件?

这是表单继承的典型情况

创建一个包含两个项目所需的所有控件的公共祖先窗体。现在为Project1继承此表单,并添加Project1只需要的控件。然后对Project2执行同样的操作(这里可能没有要添加的控件)

两个项目都包含公共表单,但每个项目只包含适合于所述项目的继承表单


尽管您可以在这里省略Project2的继承表单,但为了清晰起见,我建议您这样做。

我怀疑IDE是否能够理解条件并根据条件编辑不同的DFM。编译器对此没有问题,但IDE有。条件定义仅在编译时有效,在IDE中无效。您可以使用插件体系结构来解决此问题。创建两个DLL,它们实现一个公共接口,并在创建表单的DLL中具有ShowDialog函数。您还可以添加GetData和SetData函数来获取和设置表单中的数据。唯一的区别是存在一个
TCheckBox
,我只需在表单
OnCreate()
事件中使用
{ifdef}
隐藏它或
显示它,除非绝对必要,否则不要这样做。我继承了一个系统,因为在包装COM对象时出现了一些问题,所以有人这样做了。我最终重写了,以编程方式创建了有问题的控件。表单继承是一个很好的解决方案。但是由于这些表单在两个不同的项目中使用,我们的缺点是您仍然需要两个DFM文件。Tom Brunberg(参见注释)建议使用
{$IFDEF}
来显示或隐藏复选框,这在我的情况下更为简洁。既然Tom没有把这写下来作为可能的答案,我会接受你的…希望这和Tom的评论能成为任何寻求这类问题解决方案的人的有用补充。