3
votes

I need to loop inside a resource file and and load all BMP files with the following statement; bBitmap.Handle := LoadBitmap(hInstance, 'IMAGE_NAME');

How do I loop a resource file; do I have to do a regular IO operation and treat it like a text file? I can read each line and create a list of bitmap names than on a separate loop execute the above statement to load bitmaps. Or is there a built-in method in Delphi libraries to do this operation?

FILE_NAME_1 BITMAP "btnFile1.bmp"
FILE_NAME_2 BITMAP "btnFile2.bmp"
....

2
A resource is a binary chunk in the resource section inside the executable. There is no "resource file" once the executable is built, and it's definitely not text format. A "resource file" is a pre-compiled binary file that's linked into the executable when it's created; the resource file is created from source in a text "resource script" (unless it's pre-created as a binary file by the IDE).Ken White
Well, you could hack it so the .RC file is included as the value of a constant in your app's code. Your app could then parse the constant, retrieve all image names and load them. Something like const RC_CONTENTS = '''' {$INCLUDE MYRCFILE.RC} ''''; BUt you are probably gonna have to rename the .rc for this to work (or the res will be included twice) and you may find that getting the quotes right is gonna be a hassle if at all possible.Marjan Venema
Thank you. I see that I have to pre-define values and use them. I will try to include the values as a constant as suggested by Marjan. At worst, I will probably create an array of strings. The list of images is long though.Alex
XNResource Editior is AFAIK open source delphi. So it can list resources, you might find something there.bummi
You can use the WinAPI function EnumResourceNames, which is what I suspect XNResource Editor uses to list them (as @bummi mentioned). I don't have a Delphi example handy, and a quick SO/MSDN search doesn't turn one up, though.Ken White

2 Answers

5
votes

I suggest you have a look at the Resource Explorer demo included with your Delphi installation. You can find it in "c:\Users\Public\Documents\RAD Studio\9.0\Samples\Delphi\VCL\resXplor\resxplor.dpr" (adjust for different path/Delphi version). In the ExeImage.pas file there are classes that allow you to easily assing the resources to TPicture etc.

2
votes

EnumResourceNames as suggested by Ken White worked perfectly, and it's pretty simple to implement. Couldn't accept it as an answer because he left a comment only.

Here's my solution using the suggestion;

Inside the procedure where I load my images, I added the following lines of code;

var
  returnVal:bool;
  hMdl: HMODULE;
begin
  hMdl:=LoadLibraryEX('FileNameWithResources.exe',0,LOAD_LIBRARY_AS_DATAFILE);
  // I load bitmaps so RT_BITMAP parameter is chosen
  returnVal:=EnumResourceNames(hMdl,RT_BITMAP,@Callback,0);

@callback function returns a Boolean. You have to put this in the class level, before implementation code of the class. There's no declaration for it. My class is singleton so I call a class level procedure to add values to a TStringList. Do not return false if you have a more complex if statement and want to loop everything. If you return false at any time, calls to this function ends and you will not get rest of the resource names.

function Callback(handle:THandle;ResType:PChar;ResName:Pchar;long:Lparam):bool;stdcall;
var
      tempString: string;    
begin  
      tempString := resname;
      if length(tempString) > 0 then begin
        MyClassName.AddToResourceNames(tempString);
        result := true;
      end else
        result := false;
end;