Delphi 从资源DLL字符串表设置Unicode标题

Delphi 从资源DLL字符串表设置Unicode标题,delphi,dll,unicode,localization,Delphi,Dll,Unicode,Localization,我的UI上的Unicode字符显示不正确,这使我遇到了问题。我有一个仅限资源的DLL,其中包含用于UI本地化的字符串表。我在Delphi XE3中用一个只包含DLL的项目创建DLL(在DPR文件中只有{$R'lang.res''lang.rc'},并给我lang.DLL)。我已经验证了我的lang.rc文件是UTF-8格式,带有Windows CRLF换行符。当我从DLL加载字符串时,Unicode字符在接口上是混乱的。这里有一些细节 字符串表中的代码段: STRINGTABLE { 59,"1

我的UI上的Unicode字符显示不正确,这使我遇到了问题。我有一个仅限资源的DLL,其中包含用于UI本地化的字符串表。我在Delphi XE3中用一个只包含DLL的项目创建DLL(在DPR文件中只有
{$R'lang.res''lang.rc'}
,并给我
lang.DLL
)。我已经验证了我的lang.rc文件是UTF-8格式,带有Windows CRLF换行符。当我从DLL加载字符串时,Unicode字符在接口上是混乱的。这里有一些细节

字符串表中的代码段:

STRINGTABLE
{
59,"180˚"
60,"90˚ CW"
61,"90˚ CCW"
}
下面是一些代码片段,它们说明了我在使用Unicode字符时遇到的问题:

// explicitly assigning the degrees character shows 180˚ properly
ImageMenu180Action.Caption := '180˚'; 

// getting the resource from the DLL shows some weird two-character string for the degrees character
ImageMenu90CWAction.Caption := TLangHelper.LoadStr(IDS_ImageMenuRotationCW90);

// OutputDebugString shows the degrees character in the debugger output correctly
OutputDebugString(PChar('IDS_ImageMenuRotationCW90: '+TLangHelper.LoadStr(IDS_ImageMenuRotationCW90)));
以下是我的Delphi函数,用于从资源DLL加载字符串:

class function TLangHelper.LoadStr(ResourceId: Integer):String;
var
   Buff: String;
   L: Integer;
begin
  Result := '';
  if LangDllHandle = 0 then begin
    LangDllHandle := LoadLibrary(LANGUAGE_DLL_LOCATION);
    if LangDllHandle = 0 then begin
      ShowMessage('Error loading language localization resources.');
    end;
  end;
  if LangDllHandle <> 0 then begin
    L := 1024;
    SetLength(Buff, L+1);
    LoadString(LangDllHandle, ResourceId, PChar(Buff), L);
    Result := String(PChar(Buff));
  end;
end;
我发现您需要告诉资源编译器.rc文件是如何编码的。对于UTF-8,这是代码页65001,因此您可以运行以下命令:

brcc32 -c65001 lang.rc brcc32-c65001 lang.rc 然后,当然,您将从代码中的
$R
指令中删除
'lang.rc'
部分,因为您不再希望IDE调用资源编译器本身

如果您的Delphi版本足够新,那么您可以保留完整的
$R
指令,并在项目选项中设置
-c65001
选项


仅仅通过查看文件就很难知道文件的编码。可以有许多有效的猜测。
-c
选项有文档记录,但没有提到何时需要使用它,也没有提到IDE在运行资源编译器时使用了什么。IDE可能只是使用默认值,与brcc32.exe相同,这是系统的默认ANSI代码页。

字符串不应该是UTF-16而不是UTF-8吗?您从哪里看到在.rc文件中使用UTF-8会导致在.res文件中正确编码?我发现这表示您需要使用一个特殊的命令行选项来brcc32(
-c65001
)告诉它.rc文件的编码。我怀疑IDE在默认情况下会使用这个选项。@RobKennedy说的不错,非常感谢。由于缺少其他说明的文档(我找不到),我假设brcc32将默认为文件的文本编码。错误的假设。看来这些东西应该有更好的记录。我不可能是唯一一个想这么做的人。如果你想写一个答案,我会接受。资源编译器会将文本转换为UTF-16。你能不能将项目->选项->资源编译器->附加选项设置为
-c65001
(这里使用Delphi XE3)?这对我很管用。谢谢你提到这一点。我已经更新了答案。我使用的Delphi的上一个版本没有这个选项。一个非常好的问题的非常好的答案!还有一件事,至少在XE3上。如果从.dpr文件中的
$R
指令中删除
'lang.rc'
(因此只有
{$R'lang.res'}
),它仍然会在
部分的.dproj文件中保留,并且每次都会编译.rc。您必须手动删除
,才能将其从生成中实际删除。我称之为bug。如果您在编辑器中手动删除它,那么它就不是bug。如果IDE没有正确删除它,那么它就是一个bug。可以通过IDE将.rc文件从项目经理的源文件列表中删除,从而将其删除。如果您这样做了,并且它没有从.dproj文件中删除,那么我将称之为bug。 brcc32 -c65001 lang.rc