【问题标题】:Why is my Delphi 2010 resource dll file ANSI Encoded为什么我的 Delphi 2010 资源 dll 文件是 ANSI 编码的
【发布时间】:2015-08-24 22:42:53
【问题描述】:

我使用 Delphi 2010 中的资源 DLL 向导为我的程序生成仅资源 dll。当我使用 Notepad++ 查看它们时,它们似乎使用的是 ANSI 编码。我错过了一些设置吗? unicode 程序似乎不应该将其资源存储在 ANSI 中,尤其是对于亚洲语言。

我专门查看了 TABOUTBOX RT_RCDATA 记录。我尝试使用以下代码加载它,

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;

我得到了垃圾,但是当我将 ResStr 的类型更改为 AnsiString 时,它显示正确。在 Notepad++ 中打开文件我可以看到对话框资源似乎是 ansi,包括标签标题。

【问题讨论】:

  • 字符串资源总是以 Unicode 格式存储(参见The format of string resources)。这是规范的一部分。是什么让您认为它们是 ANSI?
  • @Remy - Old New Thing 文章专门针对 RT_STRING 资源。在这种情况下,资源是一个 RT_RCDATA(应用程序定义)。
  • 相关资源是二进制 DFM 资源,而不是字符串资源。

标签: delphi localization translation delphi-2010


【解决方案1】:

资源 DLL 向导为本地化 DFM 创建 RCDATA 资源。名为TABOUTBOX 的RCDATA 资源是二进制DFM 资源。存储在 DFM 中的字符串值(组件名称、标题等)在现代 Delphi 版本(包括 2010)中使用 UTF8 编码。但 DFM 数据本身本质上是二进制的,它代表了序列化组件的完整结构。它本身不是 Unicode 数据,因此您不能将其按原样加载到 UnicodeString 中(当您将 ResStr 更改为 AnsiString 时,它“工作”,但仅仅是因为它的 8 位性质)。 DFM 资源用于TForm/TDataModule/TFrame 派生类(在本例中为TAboutBox)在运行时加载和反序列化。

如果要将 DFM 资源视为人类可读的文本,则必须使用 ObjectBinaryToText()ObjectResourceToText() 函数对其进行解码。例如:

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;

【讨论】:

  • 将“ObjectResourceToText”更改为“ObjectBinaryToText”并将“ResStrm.DataString”更改为“StrStrm.DataString”后,它按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
相关资源
最近更新 更多