2

Delphi 2007/2009 odd question here:

It's possible, based on a component property defined in design-time, to include files in linking or leave them ?

Example: If I leave SomeProperty true, when compiling, the unit SomeUnit will be included into my project. Otherwise it will not be included.

My second approach to this problem is to deploy a second component, which when dropped in the form (or not) will include the unit in uses clause. But if it can be done with a property, that'll be better.

I want to avoid conditional compilation via IFDEF because that forces the component to be built every time the projects are built. Or not?

I am trying to achieve an easy way of including some units in project, and then those units will provide support for specific databases. Having these into an option, at the connection component, will be ideally easy: Check support and that's done. Uncheck, and get some less KBs in your compiled APP.

edit: I'll stay with the component way for instance. I knew the IFDEF method and things, but that forces the component to be built everytime the projects are built. Or not?

I was trying to achieve an easy way of including some units in project, and then that units will provide support for specific databases. Having these into an option, at the connection component, will be ideally easy: Check support and that's done. Uncheck, and get some less KBs in your compiled APP.

4

6 回答 6

6

不。

你想解决什么问题?

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

于 2009-01-13T19:53:54.373 回答
4

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

{$DEFINE youridentifier}

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

{.$DEFINE youridentifier}

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

于 2009-01-13T20:08:36.247 回答
3

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

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

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

于 2009-01-13T19:58:21.883 回答
1

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

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

于 2009-01-16T16:15:51.107 回答
1

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

于 2009-01-14T16:55:37.447 回答
1

您可以使用 DesignIntf​​.RegisterSelectionEditor 注册选择编辑器(请参阅 Delphi 源代码中有关 ISelectionEditor 的注释),然后使用 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;
于 2010-07-10T01:03:21.370 回答