【问题标题】:Is possible to include files (linking) based on a component property?是否可以基于组件属性包含文件(链接)?
【发布时间】:2010-10-01 05:17:44
【问题描述】:

Delphi 2007/2009 奇怪的问题在这里:

根据设计时定义的组件属性,是否可以在链接中包含文件或保留它们?

示例:如果我将 SomeProperty 设置为 true,则在编译时,单元 SomeUnit 将包含在我的项目中。否则不会被收录。

我解决此问题的第二种方法是部署第二个组件,当将其放入表单(或不放入)中时,将包含使用子句中的单元。但如果可以用属性来完成,那就更好了。

我想避免通过 IFDEF 进行条件编译,因为这会在每次构建项目时强制构建组件。还是不行?

我正在尝试以一种简单的方式在项目中包含一些单元,然后这些单元将为特定数据库提供支持。在连接组件中将这些选项纳入一个选项将非常容易:检查支持并完成。取消选中,并在您编译的 APP 中获得更少的 KB。

编辑:例如,我将继续使用组件方式。我知道 IFDEF 方法和东西,但是每次构建项目时都会强制构建组件。还是不行?

我试图实现一种在项目中包含一些单元的简单方法,然后这些单元将为特定数据库提供支持。在连接组件中将这些选项纳入一个选项将非常容易:检查支持并完成。取消选中,并在您编译的 APP 中获得更少的 KB。

【问题讨论】:

    标签: delphi pascal conditional-compilation


    【解决方案1】:

    没有。

    你想解决什么问题?

    您可以添加一个后编译步骤,该步骤可以选择包含一些基于组件属性的资源 - 但您必须进行一些编码才能实现这样的功能。

    【讨论】:

      【解决方案2】:

      编写一个 IDE 插件。处理“编译前”通知并检查项目中是否有任何表单或数据模块具有您感兴趣的类型的组件,然后检查它们的属性。根据您在那里找到的内容,您可以尝试修改一个单元的内容以使用您选择的另一个单元。这听起来确实不容易,但似乎有可能。

      你的第二个想法很简单。例如,这正是 TXPManifest 组件所做的事情。请注意,从表单中删除此类组件不会“取消使用”关联的单元。

      要有条件地添加对不同数据库的支持,您可以考虑使用运行时包。 (毕竟,这就是 IDE 设法支持这么多不同类型的组件的方式。)将每个数据库的自定义代码放入不同的包中。然后,您支持的数据库只是在运行时具有可用包的数据库。无需编译时或设计时配置。然而,这样做的障碍是管理哪些包可用,并确定其中哪些是提供数据库支持的包。

      【讨论】:

        【解决方案3】:

        您可以使用 {$IFDEF youridentifier} 可选代码 {$ENDIF} 方法有条件地将数据编译到您的应用程序中,然后启用它只需转到您的项目选项并将 youridentifier 输入到相应的选项字段中。另一种方法是将以下内容添加到单元顶部(或包含文件中):

        {$DEFINE youridentifier}

        这将强制你的标识符打开。要禁用,只需在 $: 之前放置一个句点:

        {.$DEFINE youridentifier}

        使用这些技术可以很容易地在每次编译时有条件地引入代码或替换代码。

        【讨论】:

        • +1,这似乎是有条件地包含文件的最佳方式。它具有可用于命令行构建/自动构建的额外好处。
        【解决方案4】:

        您的第二种方法不一定会按您希望的方式工作。当您将组件放到表单上时,Delphi 会帮助您将必要的单元添加到您的使用列表中,但在您删除组件时它不会删除该单元。即使您不使用组件或从该单元导出的任何其他实体,当 initialization 或 中有代码时,该单元仍有可能链接到您的应用程序>finalization单元的一部分。不幸的是,这种情况经常发生,即使可以按需初始化东西。

        【讨论】:

          【解决方案5】:

          没有办法按照您的要求进行操作,但您可能不知道的是,包含在您的使用列表中但从未被引用的单元将对您的可执行文件的大小产生最小的影响。 Delphi 中的智能链接器在删除从未使用过的代码方面做得非常好。如果您对组件引用的“可选单元”很小心,并且其中没有任何全局执行的代码(所有内容都包含在一个或多个类中),那么它是否无关紧要在uses子句中并且没有使用,或者根本不在uses子句中。

          这将很容易让您做我认为您想做的事情,即在表单上放置一个组件,该表单包含一个单元,然后可以链接到您的应用程序。删除该组件将具有不在单元中链接的效果。然而,我相信,在已使用单元中的任何资源(例如表单或 $R 指令包含的其他项目)仍将包含在可执行文件中。

          【讨论】:

            【解决方案6】:

            您可以使用 DesignIntf​​.RegisterSelectionEditor 注册选择编辑器(请参阅 Delphi 源代码中有关 ISelectionEditor 的 cmets),然后使用 RequiresUnits 过程在 uses 子句中包含额外的单位。

            TMySelectionEditor = class(TSelectionEditor)
            public
              procedure RequiresUnits(Proc: TGetStrProc); override;
            end;
            
            procedure Register;
            
            implementation
            
            procedure TMySelectionEditor.RequiresUnits(Proc: TGetStrProc);
            var
              comp: TMyComponent;
              I: Integer;
            begin
              inherited RequiresUnits(Proc);
              Proc('ExtraUnit');  
              // might be a better way of doing the code from here onwards?
              if (Designer=nil)or(Designer.Root=nil) then Exit;
            
              for I := 0 to Designer.Root.ComponentCount - 1 do
              begin
                  if (Designer.Root.Components[i] is TMyComponent) then
                  begin
                    comp := TMyComponent(Designer.Root.Components[i]);
                    if comp.SampleProperty = True then
                        Proc('ExtraUnit2');
                    Proc(comp.ObjProperty.UnitName);
                  end;
              end;
            end;
            
            procedure Register;
            begin
              RegisterSelectionEditor(TMyComponent, TMySelectionEditor);
            end;
            

            【讨论】:

            • 确实应该有比这更简单的方法,很容易将 TComponent 的单元添加到 uses 子句中,但只要它是在设计时动态创建的 TPersistent,或者是事件中的类型不存在于组件类中的任何一个单元中,那么添加起来就会变得更加困难。
            • 何时调用选择编辑器 - 仅当开发人员在表单上放置一个新组件时?在这种情况下,SampleProperty 仍将具有默认值,更改为不同的值将无效。
            • 不行,好像只有编译的时候才会调用(每个组件一次),所以要看当时属性的值。似乎没有办法引用正在处理的组件,因此这段代码循环遍历放置在表单上的所有组件(您可能需要修改以允许子属性)
            猜你喜欢
            • 2012-07-10
            • 2012-03-21
            • 2011-03-25
            • 2010-12-06
            • 1970-01-01
            • 1970-01-01
            • 2021-10-15
            • 2019-10-12
            • 2011-02-26
            相关资源
            最近更新 更多