2

I try to include resource files in my package. When I construct the package, I read this warning :

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

In my unit I write : ...
end;

{$R Project.dres}

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

The ressources load well, but why I'have a warning ?

Joc02
  • 345
  • 8
  • 18
  • I've find a begining of response. In the .dpk I've "*.res" and "*.dres". If I remove it, I don't get the warning. But when, in a project, I use a component with a ressource, I get this message "Ressource not found" – Joc02 Oct 21 '14 at 15:00
  • Related: https://stackoverflow.com/questions/8115824/duplicate-resource-warning-from-same-file – Gabriel Mar 21 '22 at 10:03
  • Relatd: https://stackoverflow.com/questions/71518287/h2161-warning-duplicate-resource-type-10-rcdata-id-tfrmabout – Gabriel Mar 21 '22 at 10:03

3 Answers3

6

Sometimes the IDE gets confused. Check your .DPR file (using the Project->View Source menu item). There should be only one {$R *.RES} entry; the IDE sometimes adds one on the right end of one of the units listed.

(The sample I've shown is for an application, but the same can apply to a package source file.)

Correct:

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.

Incorrect, and will cause the duplicate resource error (note extra resource directive on second line of 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.
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • The question talks of a .dres file which is the compiled output from the resources and images dialog. – David Heffernan Oct 22 '14 at 06:33
  • @David: The problem's still the same. There are duplicate inclusions of the same resource, most likely caused by the line the poster indicated with `I write...{$R Project.dres}`, because the `{$R *.dres}` that the IDE adds will include that same file (the one named the same as the project). Using the resources and images dialog adds the `{$R}` automatically, so there's no need for Joc02 to have to "write" it. – Ken White Oct 22 '14 at 12:31
1

This is my synopsis of what you have done:

  • You are working on a package project.
  • You have added some files to the project using the Resources and Images dialog from the Project menu.
  • You have added the line {$R Project.dres} to one of the units contained in that package.

The compiler then reports, at link time, that it has been asked to link multiple copies of the file Project.dres. The compiler won't do this and discards one of the compiled resource files.

The key to understanding this can be found in your package's main file, the .dpk file. It will look like this:

package Package1;

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

When you use the Resources and Images dialog in the IDE the IDE stores the information in the project file, the .dproj file, and also adds {$R *.dres} to the main project source file. And that's the line that can be seen above. The * in a $R directive instructs the compiler to use the same base name as the file in which the $R directive appears.

So this is how you end up with multiple references to the same .dres file. The compiler expands the {$R *.dres} in your .dpk file into Project.dres and links it.

The most natural solution would be to delete the {$R Project.dres} from the .pas source unit in which it appears.

However, it is possible that the reason why you placed it in the source file is that you use the source file in other projects and want it to stand alone. The source file contains the code that loads the resource and it makes sense to ensure that whenever a project includes this source file, it also includes the resource. A $R directive will do that. But that's not compatible with using the IDE's Resources and Images dialog. That IDE mechanism relies on saving the information to .dproj files and is a project centric mechanism.

So, it you want the source .pas file to include the $R directive here is what to do:

  1. Remove all the items from the Resources and Images dialog.
  2. Makes sure there are no references to the .dres file in any source file, including .dpk and .dpr files.
  3. Create a .rc resource script file that lists the resources you wish to include.
  4. Ask the compiler to compile the resource script and link it by including this directive in your .pas source file: {$R images.res images.rc}

Obviously I've just invented a file name there, but you will no doubt pick something appropriate.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thank for your help. I try it but I have 2 questions. First, when I write '{$R images.res images.rc}' the resource doesn't find. If I write '{$R images.res' that work fine. Second, if in package I create 2 uses who work with the same ressource, I've two $r, and I've the warning. – Joc02 Oct 22 '14 at 15:21
  • I cannot help you unless you are more precise. I can do nothing with "the resource doesn't find". You need to be precise and include verbatim messages. I trust you succeeded in making `images.rc`? – David Heffernan Oct 22 '14 at 15:25
  • If I write '{$R images.res images.rc}' I have this message in runtime "Le projet Project2.exe a déclenché la classe d'exception EResNotFound avec le message 'Ressource IMAGE non trouvée". If I write "{$R images.res}" that work fine – Joc02 Oct 22 '14 at 15:33
  • I guess you did something wrong. I cannot see your .rc file. – David Heffernan Oct 22 '14 at 15:34
  • If in a package I have 2 uses with '{$R ...}' for share image, I have this message during the compilation : [dcc32 Conseil] H2161 Warning: Duplicate resource: Type 10 (RCDATA), ID PLUSUTILISEVOIR; File Project.dres resource kept; file Project.dres resource discarded. – Joc02 Oct 22 '14 at 15:35
  • Yes. That's what you said in the question. I explained why that happened. You seem to be struggling very hard. You say you wrote `{$R images.res images.rc}`. Did you make a resource script file, `images.rc`? Do you know what a resource script is? Do you understand my answer very well? Have you worked with windows resources before? – David Heffernan Oct 22 '14 at 15:41
  • @David: Im surprised that step 4 works in a *.pas file. I always thought it only worked in *.dpr files (and hated that). Is this a newish feature? – Uli Gerhardt Jan 22 '15 at 13:20
  • @UliGerhardt You are probably right. It probably does only apply in the .dpr file, and only with .dproj support too. I'll check. – David Heffernan Jan 22 '15 at 13:29
  • @David: It seems the RcCompile entry in the dproj is relevant in XE6. AFAICT the $R line doesn't need to mention the *.rc file. – Uli Gerhardt Jan 22 '15 at 13:38
0

David Heffernan has show me the good way.

In my case I want share images for multi units of one package. Each unit is a component. If I add {$R xxx.res} on each unit, I have a waring : " H2161 Warning: Duplicate resource:". If I remove the {$R} on each unit for write it on the .dpk, I have a runtime error "exception EResNotFound" when I use my component on a project.

My solution is to create an unit who centralise all call's of resources. This unit have the '{$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.

In the dpk I write this :

{$R TestPackageResource.res TestPackageResource.rc}

The others units have reference one the manager but don't have a '$R' therefore no warning. In the execution time no error because the unit "manager" is loaded and the $R is applied. Each of my components can have image without warning or error.

Joc02
  • 345
  • 8
  • 18