【问题标题】:How do you deal with IFDEFs in .dpr uses section您如何处理 .dpr 使用部分中的 IFDEF
【发布时间】:2009-04-16 21:05:53
【问题描述】:

每当您向项目添加新单元时,Delphi 都会重新构建 .dpr 文件,并且使用部分中的所有 IFDEF 都消失了。

为了解决这个问题,我通常使用记事本创建新的 .pas 文件,然后手动将其添加到 .dpr 中。如果我需要一个表单,我使用 File->New->Form 然后将 .dpr 文件恢复到以前的版本。如果你问我不是很RAD ;-)

你是怎么处理的?有没有办法在保留 IFDEF 的同时在 IDE 中添加一个单元?

【问题讨论】:

  • 您能否解释一下为什么您只有时希望一个单位成为您项目的成员?我不明白目的。
  • 在我们的项目中,我们使用 Delphi 附带的 FastMM 进行发布构建,但使用外部 FastMM4.pas 进行调试构建。所以我们有一个围绕“使用 FastMM4;”的 IFDEF
  • @Ulrich:我在 DEBUG 和 RELEASE 构建中都使用 FastMM4 - 为什么不呢?它是项目 SVN 存储库的一部分,无论编译器版本如何,我都会获得相同的环境。有什么不喜欢的?
  • 我必须承认我并没有考虑太多。直觉上,我不想在(发布)项目中使用我不使用的东西。
  • @Rob:如果产品有不同的版本(便宜的和昂贵的等)会很方便,这样你就可以省略功能。

标签: delphi


【解决方案1】:

有时我会专门创建一个单元作为所有 IFDEF 和其他东西的地方,如果它在 dpr 中,IDE 会搞砸。该单元通常位于 dpr 的 uses 子句的顶部。这个技巧并不适合所有场景,但有时可以省去很多繁琐的工作。

【讨论】:

  • +1。我不记得曾经使用过条件包含单位。为什么要这样做?
  • @mghie:跨编译器和 RTL 版本的可移植性。跨编译器的可移植性(Delphi vs. C++ Builder。)根据构建配置避免包含单元(例如,您可能不希望在发布构建中支持堆栈转储,因为没有调试符号。)和其他一百种场景。跨度>
  • 首先,这不会导致有条件包含的单元成为项目的一部分(因此可以通过项目经理访问)
  • @mghie:内存管理器必须是链接器看到的第一个单元,这只能通过 .dpr 文件实现。这就是我所指的用例(我也在使用 FastMM,除了在某些应用程序中我遇到了错误,并且必须在 .dpr 文件中维护 IFDEF 以测试各种版本。)
  • 是的,我用额外的单元做了这个,但只是因为如果我把 IFDEF 放在 dpr 中,Delphi 会感到困惑。
【解决方案2】:

我没有将任何 ifdef 放入 dpr 文件中。如果我想在一个项目中使用不同的单位/形式,根据某些条件,我将项目一分为二。

【讨论】:

    【解决方案3】:

    我花了很长时间试图解决这个问题,

    我最终为每种构建类型创建了一个项目文件 (.dpr), 项目|项目选项|目录/条件中的条件 并且只有我想要添加到项目中的单位

    此剂量的缺点是,如果您在 .dpr 中有自定义代码,则必须在更改时手动将其复制到其他项目文件中。

    正如 Rob Kennedy 所指出的,这可以通过将自定义代码放入其自己的单元中来处理,该单元由单个过程调用。从而最小化 .dpr 代码大小/要进行的更改

    另外,您获得的另一个好处是,如果您将所有 .dpr 文件添加到项目组中,您可以构建所有您的不同版本只需单击/cmd 行

    【讨论】:

    • 大多数 DPR 代码可以通过将其移动到不同的单元然后使用单行调用来保持在最低限度。这样一来,DPR 代码就不太可能需要更改。
    • 谢谢你,我更新了我的答案,我要更新我的代码;)
    【解决方案4】:

    您可以从 IDE 中手动添加它。 (在项目中使用“查看源代码”选项)。

    通常 dpr 是“隐藏的”。你不应该改变那里的任何东西。 如果你这样做了,你最好确保所有的更改都是手动的,否则你会丢失一些信息。

    【讨论】:

      【解决方案5】:

      对于表单、数据模块和其他包含单个类的单元,其功能将被替换,解决方案相当简单。只是不要将自定义单元直接添加到产品中,而是将它们保存在搜索路径中的某个位置(或修改项目搜索路径以包含它们的位置)。

      1) 创建一个新单元,其中包含所有其他类的父类,或者它们都将实现的接口(我通常更喜欢后者,因为它允许更容易定制)[例如,这被称为 uSpecialParent .pas]

      2) 添加一个类变量,当您需要创建新功能时将引用该变量。例如,如果您只是要显示模态的一堆表单,所以不关心任何其他方法,那么您可以有一个如下所示的变量:

      TYPE
        TMySpecialFormClass : class of TForm;
      
      VAR
        TMySpecialForm : TMySpecialFormClass;
      

      3) 创建另一个包含所有 IFDEFS 的单元。它可能如下所示:

      Unit uRegisterSpecialForms;
      
      interface
      
      uses
      {$IFDF SPECIAL1}
        uSpecial1,
      {$ENDIF}
      {$IFDEF SPECIAL2}
        uSpecial2,
      {$ENDIF}
        uSpecialParent;
      
      implementation
      
      // no code needed.
      
      initialization
      
      {$IFDEF SPECIAL1}
        TMySpecialForm := uSpecial1.TSpecialForm1;
      {$ENDIF}
      {$IFDEF SPECIAL2}
        TMySpecialForm := uSpecial2.TSPecialForm2;
      {$ENDIF}
      
      end.
      

      4) 要在您的代码中引用它,您只需将 uSpecialParent 添加到将请求特殊表单的单元中,然后动态创建它以显示此模式,您可以调用以下命令:

      var
        frm : TForm;
      begin
        frm := TMySpecialForm.Create(nil);
        try
          frm.showmodal;
        finally
          frm.free;
        end;
      end;
      

      【讨论】:

        【解决方案6】:

        为了完整起见,这里是低技术方法:

        在 IDE 再次弄乱了你的 uses 子句之后:

        1. 关闭项目
        2. 转到您选择的版本控制工具,并将 DPR 与最新签入的版本进行比较 使用 WinMerge 等支持合并的差异工具的版本
        3. 恢复 IDE 更改
        4. 保存 DPR
        5. 继续努力

        【讨论】:

          【解决方案7】:

          (德尔福 7)

          我也试过了。 看看下面的第一个代码版本和我的 cmets:

          program Project1;
          
          {$IFDEF TESTIFDEF}
          uses
            Forms,
            Unit1 in 'Unit1.pas' {Form1},
            Unit2 in 'Unit2.pas' {Form2};
          
          {$ELSE}
          uses
            Forms,
            Unit1 in 'Unit1.pas' {Form1};
          {$ENDIF TESTIFDEF}
          
          {$R *.res}
          
          begin
            Application.Initialize;
            Application.CreateForm(TForm1, Form1);
            Application.CreateForm(TForm2, Form2);
            Application.Run;
          end.
          

          那时,我刚刚插入了 2nd Form 并注意到相应的单元 (Unit2.pas) 被插入到 IFDEF 的第一部分内,即在“TESTIFDEF”标签部分内 - 因此没有覆盖第二个块(在 {$ELSE} 之后)。

          因此您的解决方案应该是:

          1. 定义一个像“{$IFDEF DELPHIBASISCONFIGURATION}”这样的 IFDEF 语句来代替我的“{$IFDEF TESTIFDEF}”,所有表单都将在其中添加。
          2. 为您要使用的不同配置定义尽可能多的替代标签。
          3. 每次向项目添加表单时,将第一个块的插入行复制到下面的相应块中 - 取决于您的需要...
          4. 使用定义语句或选项对话框激活所需的配置
          5. 永远不要定义“DELPHIBASISCONFIGURATION”;)

          因此,它应该如下所示:

          program Project1;
          
          {$DEFINE MYCONFIG1} // THIS ONE IS NOW ACTIVE
          
          
          {$IFDEF DELPHIBASISCONFIGURATION}
          uses
            Forms,
            Unit1 in 'Unit1.pas' {Form1},
            Unit2 in 'Unit2.pas' {Form2},
            Unit3 in 'Unit3.pas' {Form3};
          
          {$ELSE}
               // THIS IS A "COMMON TO ALL CONFIG" PART
               uses
                 Forms,
          
                 // FIRST CONFIGURATION
                 {$IFDEF MYCONFIG1}
                 Unit1 in 'Unit1.pas' {Form1},
                 Unit3 in 'Unit3.pas' {Form3}
                 {$ENDIF MYCONFIG1}
          
                 // SECOND CONFIGURATION    
                 {$IFDEF MYCONFIG2}
                 Unit1 in 'Unit1.pas' {Form1},
                 Unit2 in 'Unit2.pas' {Form2}
                 {$ENDIF MYCONFIG2}
          
               // THIS IS THE "COMMON TO ALL CONFIG" END :)
               ;
          
          {$ENDIF TESTIFDEF}
          
          {$R *.res}
          
          begin
            Application.Initialize;
            Application.CreateForm(TForm1, Form1);
            //Application.CreateForm(TForm3, Form3);
            //Application.CreateForm(TForm2, Form2);
            Application.Run;
          end.
          

          如您所见,我已经放弃了对 Form2 和 Form3 的 Application.CreateForm(...) 的调用。

          恕我直言,通常最好在您真正需要的时候动态创建补充表格,即并非所有表格都在程序启动时...

          【讨论】:

          • 这是一个非常聪明的主意。不幸的是,它不适用于 D2007,它显然理解定义并修改了“真实”部分:-(
          猜你喜欢
          • 2021-10-12
          • 1970-01-01
          • 2019-01-30
          • 2014-11-20
          • 2019-05-21
          • 1970-01-01
          • 2014-09-07
          • 2012-03-20
          • 1970-01-01
          相关资源
          最近更新 更多