Welcome to the new DelphiDabbler Code Library Documentation.

This is a new site that's currently running on alpha code. There are going to be bugs. If you discover any, please report them on the site's issues page (GitHub account required). Thanks.

Warning: Many URLs are going to change. Refer to the README file to discover which library project's documentation has been completed.

Example #2: Accessing all resources in a file

In this example we show how to scan through all the resources in a resource file, listing some information about each one. The following code fragment assumes we have created a resource file object, ResFile, and have loaded a resource file into it (see example #1). We also assume that the form contains a memo control named Memo1. Here is the code:

var
  ResFile: TPJResourceFile;
  ResEntry: TPJResourceEntry;
  EntryIdx: Integer;
begin
  ...
  // Assume ResFile contains a loaded resource file
  ...
  Memo1.Clear;
  for EntryIdx := 0 to Pred(ResFile.EntryCount) do
  begin
    ResEntry := ResFile.Entries[EntryIdx];
    Memo1.Lines.Add(
      Format(
        'Type: "%s"   Name: "%s"   LanguageID: %0.4X',
        [ResIDToStr(ResEntry.ResType), ResIDToStr(ResEntry.ResName),
        ResEntry.LanguageID]
      )
    );
  end;
  ...
  // Don't forget to free ResFile at some stage.
end;

This code uses both TPJResourceFile and TPJResourceEntry objects. The resource file’s EntryCount property tells us how many resources there are in the file. Each resource is represented by a TPJResourceEntry object obtained from the Entries array property.

We loop through all the valid indexes into Entries and store a reference to each resource entry in turn. Having got the resource entry object we now access its ResType, ResName and LanguageID properties to get the information we want to display.

The details of each entry are formatted by Delphi’s Format function and added to Memo1. Note that we use the ResIDToStr helper function to get string representations of the resource type and name. We display the language ID as a four digit hex number since its value is a Word.

You may have noticed that we have not freed any of the resource entry objects. This is not necessary since they are all freed automatically when the resource files object is freed.

Alternative Approach [~>1.1]

A second approach to the problem uses the fact that v1.1 of the resource files unit implements an enumerator for TPJResourceFile. This means that we can use a for..in loop to enumerate the resources.

Here’s the modified code:

var
  ResFile: TPJResourceFile;
  ResEntry: TPJResourceEntry;
begin
  ...
  // Assume ResFile contains a loaded resource file
  ...
  Memo1.Clear;
  for ResEntry in ResFile do
  begin
    Memo1.Lines.Add(
      Format(
        'Type: "%s"   Name: "%s"   LanguageID: %0.4X',
        [ResIDToStr(ResEntry.ResType), ResIDToStr(ResEntry.ResName),
        ResEntry.LanguageID]
      )
    );
  end;
  ...
  // Don't forget to free ResFile at some stage.
end;

The code above requires Delphi 2005 or later. Users of earlier Delphis can still use the enumerator if desired, like this:

var
  ResFile: TPJResourceFile;
  ResEntry: TPJResourceEntry;
  Enum: TPJResourceFileEnumerator;
begin
  ...
  // Assume ResFile contains a loaded resource file
  ...
  Memo1.Clear;
  Enum := ResFile.GetEnumerator;
  try
    while Enum.MoveNext do
    begin
      ResEntry := Enum.Current;
      Memo1.Lines.Add(
        Format(
          'Type: "%s"   Name: "%s"   LanguageID: %0.4X',
          [ResIDToStr(ResEntry.ResType), ResIDToStr(ResEntry.ResName),
          ResEntry.LanguageID]
        )
      );
   end;
  finally
    Enum.Free;
  end;
  ...
  // Don't forget to free ResFile at some stage.
end;

Links: