如何确定自定义TComponent所在的DFM路径?

Adr*_*ire 3 delphi designer tcustomcontrol

在自定义中,我需要获取使用 的或文件TComponent的路径。显然,这仅在设计时需要。*.dfm*.pasTComponent

语境

与上一个问题类似:
How to detector the dfm/project path from a custom control while in the Designer?

我创建了一个类似于 TImageCollection 的自定义 TControl,但具有所有应用程序的共享图像数据库。为此,控件读取一个项目元文件,该文件是一个 XML,其中包含要包含在图像集合中的图像列表。在设计器中,图像是直接从图像文件中读取的,但在运行时,图像位于编译期间生成的资源(*.res)文件中。

if csDesigning in Self.ComponentState then
  loadImagesFromFiles(...)
else
  loadImagesFromResource(...)
Run Code Online (Sandbox Code Playgroud)

在以前的版本中(对于上面链接的其他问题),我尝试获取项目的路径,虽然这似乎不可能,但我找到了一种获取活动项目路径的方法。然而,当 IDE 打开多个项目时,这就很成问题了。

我决定改用另一种方法,即使用相对于使用组件的 DFM 的路径。这个应该比较靠谱。

TComponent不幸的是,对于放置在 DFM 上的自定义程序来说,了解 DFM 的位置似乎并不容易。

解决方案(一半)

我尝试了几种解决方案IOTA,但还没有任何效果。

此处提供的方法将路径返回到自身TComponent,而不是返回到使用它的 DFM。

我设法遵循相同的策略迭代模块,但找到哪个模块包含给定的模块TComponent并不简单:

function GetCurrentDfmPath(AComponent: TComponent): String;
var
  ModuleServices: IOTAModuleServices;
  Module: IOTAModule;
  idx: integer;
begin
  Result := '';
  SourceEditor := nil;

  if SysUtils.Supports(BorlandIDEServices, IOTAModuleServices,
    ModuleServices) then
  begin
    for idx := 0 to ModuleServices.ModuleCount - 1 do
    begin
      Module := ModuleServices.Modules[idx];

      // Needs to match the module that contains AComponent.?

    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 7

在设计时,您的组件Owner应该是父表单(默认情况下,在设计时放置在表单上的所有组件都归该表单所有)。

如果您的组件派生自TControl,它也可以使用该Forms.GetParentForm()函数找到其父 Form。

TCustomForm具有在设计时非零的Designer类型属性。IDesignerHook

使用运算符查询IDesignerHookfor (不要使用硬转换!)。IDesigneras

IDesigner有一个ModuleFileNames()方法来检索与正在设计的对象关联的文件名,在本例中为 the,TCustomForm因此参数将输出(VCL) 或(FMX)FormFileName的文件名。.dfm.xfm