H2161警告:资源重复:类型10(RCDATA)

时间:2014-10-20 14:30:50

标签: delphi package embedded-resource delphi-xe6

我尝试在我的包中包含资源文件。当我构建包时,我读到了这个警告:

[dcc32 Conseil] H2161 Warning: Duplicate resource:  Type 10 (RCDATA), ID PLUSUTILISEVOIR; File Project.dres resource kept; file Project.dres resource discarded.

我的单位写道:     ...
    端;

{$R Project.dres}

implementation
...
Button.Picture.LoadFromResourceName(HInstance, 'Image1');
...

资源负载很好,但为什么我会收到警告?

3 个答案:

答案 0 :(得分:3)

有时IDE会感到困惑。检查.DPR文件(使用 Project-> View Source 菜单项)。应该只有一个{$R *.RES}条目; IDE有时会在列出的其中一个单元的右端添加一个。

(我显示的示例是针对应用程序的,但同样适用于包源文件。)

正确:

program MaintMockup;

uses
  Vcl.Forms,
  NewMaintenanceDlg in 'NewMaintenanceDlg.pas' {Form2},
  Validations in '..\Validations.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

不正确,会导致重复资源错误(请注意uses第二行的额外资源指令):

program MaintMockup;

uses
  Vcl.Forms,
  NewMaintenanceDlg in 'NewMaintenanceDlg.pas' {Form2}, {$R *.RES}
  Validations in '..\Validations.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

答案 1 :(得分:1)

这是我对你所做的事情的概要:

  • 您正在开发一个包项目。
  • 您已使用项目菜单中的资源和图片对话框向项目添加了一些文件。
  • 您已将行{$R Project.dres}添加到该软件包中包含的其中一个单元。

然后,编译器在链接时报告已要求它链接文件Project.dres的多个副本。编译器不会这样做并丢弃其中一个已编译的资源文件。

理解这一点的关键可以在你的软件包的主文件.dpk文件中找到。它看起来像这样:

package Package1;

{$R *.res}
{$R *.dres}
....

当您在IDE中使用“资源和图像”对话框时,IDE会将信息存储在项目文件,.dproj文件中,并将{$R *.dres}添加到主项目源文件中。这就是上面可以看到的那条线。 *指令中的$R指示编译器使用与$R指令所在文件相同的基本名称。

这就是你最终对同一个.dres文件进行多次引用的方法。编译器将.dpk文件中的{$R *.dres}扩展为Project.dres并将其链接。

最自然的解决方案是从显示它的{$R Project.dres}来源单元中删除.pas

但是,将源文件放在源文件中的原因可能是您在其他项目中使用源文件并希望它独立存在。源文件包含加载资源的代码,确保每当项目包含此源文件时,它都包含资源。 $R指令将执行此操作。但这与使用IDE的“资源和图像”对话框不兼容。 IDE机制依赖于将信息保存到.dproj文件,并且是一种以项目为中心的机制。

所以,你希望源.pas文件包含$R指令这里是做什么的:

  1. 从“资源和图像”对话框中删除所有项目。
  2. 确保在任何源文件中都没有对.dres文件的引用,包括.dpk和.dpr文件。
  3. 创建一个.rc资源脚本文件,列出您希望包含的资源。
  4. 要求编译器编译资源脚本并通过在.pas源文件中包含此指令来链接它:{$R images.res images.rc}
  5. 显然我刚刚在那里发明了一个文件名,但毫无疑问你会选择合适的文件名。

答案 2 :(得分:0)

David Heffernan告诉我好方法。

在我的情况下,我希望共享一个包的多个单元的图像。每个单元都是一个组件。如果我在每个单元上添加{$ R xxx.res},我有一个警告:“H2161警告:重复资源:”。如果我删除每个单元上的{$ R}以便在.dpk上写它,当我在项目中使用我的组件时,我有一个运行时错误“异常EResNotFound”。

我的解决方案是创建一个集中所有资源调用的单位。这个单位有'{$ R}'

unit ResourceManager;

interface

uses Graphics, Classes;

type
    TResourceManager = class
    public type
        TYImageList = (acorn, address_bar);
    public
        class procedure LoadImage(ilImage: TYImageList; imgResult: TBitmap); overload;
    end;

implementation

uses TypInfo;

{$R 'TestPackageResource.res'}
{ TResourceManager }

class procedure TResourceManager.LoadImage(ilImage: TYImageList; imgResult: TBitmap);
begin
    imgResult.LoadFromResourceName(hInstance, GetEnumName(TypeInfo(TYImageList), integer(ilImage)));
end;

end.

在dpk中我写了这个:

{$R TestPackageResource.res TestPackageResource.rc}

其他单位参考经理,但没有'$ R',因此没有警告。 在执行时没有错误,因为加载了单元“manager”并且应用了$ R.我的每个组件都可以有图像,没有警告或错误。