为什么我的Delphi 2010资源dll文件是ANSI编码的

Koo*_*t33 2 delphi translation localization delphi-2010

我使用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;
Run Code Online (Sandbox Code Playgroud)

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

Rem*_*eau 8

Resource DLL向导为本地化的DFM创建RCDATA资源.命名的RCDATA资源TABOUTBOX是二进制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;
Run Code Online (Sandbox Code Playgroud)