为什么我的 Delphi 2010 资源 dll 文件是 ANSI 编码的
Why is my Delphi 2010 resource dll file ANSI Encoded
我在 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,包括标签标题。
资源 DLL 向导为本地化的 DFM 创建 RCDATA 资源。名为 TABOUTBOX
的 RCDATA 资源是二进制 DFM 资源。存储在 DFM 中的字符串值(组件名称、标题等)在现代 Delphi 版本(包括 2010)中使用 UTF8 编码。但是 DFM 数据本身本质上是二进制的,它表示序列化组件的完整结构。它本身不是 Unicode 数据,因此您不能将它 as-is 加载到 UnicodeString
中(当您将 ResStr
更改为 AnsiString
时它是 "works",但是只是因为它的 8 位性质)。 DFM 资源用于 TForm
/TDataModule
/TFrame
派生的 类(在本例中为 TAboutBox
)在运行时加载和 de-serialize .
如果您想将 DFM 资源视为 human-readible 文本,则必须使用 ObjectBinaryToText()
or 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;
我在 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,包括标签标题。
资源 DLL 向导为本地化的 DFM 创建 RCDATA 资源。名为 TABOUTBOX
的 RCDATA 资源是二进制 DFM 资源。存储在 DFM 中的字符串值(组件名称、标题等)在现代 Delphi 版本(包括 2010)中使用 UTF8 编码。但是 DFM 数据本身本质上是二进制的,它表示序列化组件的完整结构。它本身不是 Unicode 数据,因此您不能将它 as-is 加载到 UnicodeString
中(当您将 ResStr
更改为 AnsiString
时它是 "works",但是只是因为它的 8 位性质)。 DFM 资源用于 TForm
/TDataModule
/TFrame
派生的 类(在本例中为 TAboutBox
)在运行时加载和 de-serialize .
如果您想将 DFM 资源视为 human-readible 文本,则必须使用 ObjectBinaryToText()
or 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;