是否可以包含基于组件属性的文件(链接)?

发布于 2024-07-12 06:31:29 字数 598 浏览 13 评论 0原文

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

基于设计时定义的组件属性,可以在链接中包含文件还是保留它们?

示例:如果我将 SomeProperty 保留为 true,则在编译时,单元 SomeUnit 将包含在我的项目中。 否则将不会被包括在内。

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

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

我正在尝试实现一种简单的方法,将一些单元包含在项目中,然后这些单元将为特定数据库提供支持。 将这些纳入连接组件的选项中将非常简单:检查支持即可完成。 取消选中,可以在编译的 APP 中减少一些 KB。

编辑:例如,我将继续使用组件方式。 我知道 IFDEF 方法和相关知识,但这迫使每次构建项目时都必须构建组件。 或不?

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一绘本一梦想 2024-07-19 06:31:29

不,

你想解决什么问题?

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

No.

What are you trying to solve?

You could add a postcompiling step that would optionally include some resource based on a component property - but you'd have to do some coding to implement such a feature.

相思故 2024-07-19 06:31:29

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

{$DEFINE youridentifier}

这将强制启用 youridentifier。 要禁用,只需在 $ 之前放置一个句点:

{.$DEFINE youridentifier}

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

You can use the {$IFDEF youridentifier} optional code {$ENDIF} method to conditionally compile data in to your application and then to enable it just go to your project options and enter youridentifier into the appropriate option field. Another method of doing this is to add the following to the top of your unit (or in an include file):

{$DEFINE youridentifier}

which will force youridentifier on. To disable, just place a period right before the $:

{.$DEFINE youridentifier}

Using these techniques its easy to conditionally bring in code or replace code with each compile.

俯瞰星空 2024-07-19 06:31:29

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

你的第二个想法很简单。 例如,这正是 TXPManifest 组件的作用。 请注意,从表单中删除此类组件不会“废弃”关联的单元。

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

Write an IDE add-in. Handle the "before compile" notification and check whether any forms or data modules in the project have components of the type you're interested in, and then check their properties. Based on what you find there, you can try modifying the contents of a unit to use the other unit of your choice. It certainly doesn't sound easy, but it seems possible.

Your second idea is very easy. It's exactly what the TXPManifest component does, for example. Beware that removing such a component from a form does not "unuse" the associated unit.

To conditionally add support for different databases, you might consider using run-time packages. (That's how the IDE manages to support so many different kinds of components, after all.) Put each database's custom code into a different package. Then, the databases you support are simply whichever ones have packages available at run time. No compile-time or design-time configuration required. The obstacle to this, however, is to manage which packages are available, and determine which of them are the packages that provide database support.

2024-07-19 06:31:29

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

Your second approach will not necessarily work the way you want it to. While Delphi will helpfully add the necessary unit to your uses list when you drop the component onto the form, it will not remove the unit when you delete the component. And even if you don't use the component or any other exported entitiy from that unit, it is possible that the unit will be linked to your application anyway, when there is code in the initialization or finalization part of the unit. This is unfortunately very often the case, even when it would be possible to initialize stuff on-demand.

烙印 2024-07-19 06:31:29

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

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

There is no way to do what you are asking, but something you might not be aware of is that units which are included in your uses list but never referenced will have a minimal impact on the size of your executable. The smart linker that is in Delphi does a very good job of removing code which is never used. If you are careful about your "optional unit" which is referenced by the component, and don't have any code in it which is executed globally (everything is self contained in a class or classes) then it shouldn't matter if it is in the uses clause and not used, or not in the uses clause at all.

This would easily allow you to do what I think your wanting to do, which would be to drop a component on a form which includes a unit that then can be linked to your application. Removing the component would have the effect of not linking in the unit. I believe, however, that any resources (for example forms or other items included by the $R directive) which are in the used unit would still be included in the executable.

南城旧梦 2024-07-19 06:31:29

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

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;

You could use DesignIntf.RegisterSelectionEditor to register a selection editor (see comments in Delphi source code about ISelectionEditor), then use the RequiresUnits procedure to include extra units in uses clause.

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文