2

I used the Resource DLL Wizard in Delphi 2010 to generate resource only dll's for my program. When I look at them using Notepad++ it seems they are using ANSI encoding. Is there some setting I missed? It doesn't seem like a unicode program should store it's resources in ANSI especially for Asian languages.

I was looking specifically at the TABOUTBOX RT_RCDATA record. I tried to load it using the following code,

procedure LoadFromResFile(const FileName: string);
var
  LibHandle: THandle;
  ResourceLocation: HRSRC;
  ResourceSize: dword;
  ResourceHandle: THandle;
  ResourcePointer: pointer;
  ResStr: string;
begin
  LibHandle := LoadLibraryEx(PWideChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  if LibHandle > 0 then
  begin
    ResourceLocation := FindResource(LibHandle, 'TABOUTBOX', RT_RCDATA);
    ResourceSize := SizeofResource(LibHandle, ResourceLocation);
    ResourceHandle := LoadResource(LibHandle, ResourceLocation);
    ResourcePointer := LockResource(ResourceHandle);
    if ResourcePointer <> nil then
    begin
      SetLength(ResStr, ResourceSize);
      CopyMemory(@ResStr[1], ResourcePointer, ResourceSize);
      FreeResource(ResourceHandle);
    end;
    FreeLibrary(LibHandle);
  end else
  begin
    ResStr := SysErrorMessage(GetLastError);
    ShowMessage(ResStr);
  end;

I got garbage, but when I changed the type of ResStr to AnsiString, it showed up correctly. Opening the file in Notepad++ I can see that the dialog resources appear to be ansi, including the label captions.

Koot33
  • 304
  • 2
  • 10
  • String resources are ALWAYS stored as Unicode (see [The format of string resources](http://blogs.msdn.com/b/oldnewthing/archive/2004/01/30/65013.aspx)). That is part of the specification. What makes you think they are ANSI? – Remy Lebeau Aug 25 '15 at 00:27
  • @Remy - that Old New Thing article is specifically about RT_STRING resources. In this case, the resource is an RT_RCDATA (application defined). – Deltics Aug 25 '15 at 04:17
  • The resource in question is a binary DFM resource, not a string resource. – Remy Lebeau Aug 25 '15 at 04:54

1 Answers1

8

The Resource DLL wizard creates RCDATA resources for localized DFMs. The RCDATA resource named TABOUTBOX is a binary DFM resource. String values stored within a DFM (component names, captions, etc) are encoded using UTF8 in modern Delphi versions, including 2010. But the DFM data itself is binary in nature, it represents the complete structure of serialized components. It is not itself Unicode data, so you can't load it as-is into a UnicodeString (it "works" when you change ResStr to an AnsiString, but only because of its 8bit nature). DFM resources are meant for TForm/TDataModule/TFrame-derived classes (in this case, TAboutBox) to load and de-serialize at runtime.

If you want to view a DFM resource as human-readible text, you have to use the ObjectBinaryToText() or ObjectResourceToText() function to decode it. For example:

var
  LibHandle: THandle;
  ResStrm: TResourceStream;
  StrStrm: TStringStream;
  ResStr: string;
begin
  LibHandle := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  if LibHandle > 0 then
  begin
    try
      ResStrm := TResourceStream.Create(LibHandle, 'TABOUTBOX', RT_RCDATA);
      try
        StrStrm := TStringStream.Create;
        try
          ObjectBinaryToText(ResStrm, StrStrm);
          StrStrm.Position := 0;
          ResStr := StrmStrm.DataString;
        finally
          StrStrm.Free;
        end;
      finally
        ResStrm.Free;
      end;
    finally
      FreeLibrary(LibHandle);
    end;
  end else
  begin
    ResStr := SysErrorMessage(GetLastError);
  end;
  ShowMessage(ResStr);
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • After changing "ObjectResourceToText" to "ObjectBinaryToText" and "ResStrm.DataString" to "StrStrm.DataString" it works as expected. – Koot33 Aug 25 '15 at 16:42