Почему кодируется файл ANSI моего ресурса Delphi 2010

Я использовал Resource DLL Wizard в Delphi 2010, чтобы генерировать только 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, включая заголовки меток.

1 ответ

Решение

Мастер Resource DLL создает ресурсы RCDATA для локализованных DFM. Ресурс RCDATA с именем TABOUTBOX это двоичный ресурс DFM. Строковые значения, хранящиеся в DFM (имена компонентов, подписи и т. Д.), Кодируются с использованием UTF8 в современных версиях Delphi, включая 2010. Но сами данные 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;
Другие вопросы по тегам