2

情况是:

unit abc;

interface

resourcestring
  aabbcc = 'my text here';

implementation

end.

从我的应用程序中,我收到了错误代码“aabbcc”。可以使用错误代码访问资源名称 aabbcc 吗?

4

2 回答 2

4

我想您正在要求具有以下签名和行为的函数:

function GetNamedResourceString(const Name: string): string;

Assert(GetNamedResourceString('aabbcc') = 'my text here');

资源字符串存储在程序中的字符串表资源中,其中每个字符串都有一个数字索引。您在程序中使用的命名标识符在运行时不会保存在任何地方。因此,没有内置的方法来获取文本'aabbcc'并发现它与哪个字符串资源相关联。

但是,有一种方法可以在代码中获取 Delphiresourcestring标识符并发现其数字 ID。将表达式类型@aabbcc转换为PResStringRec,然后读取其Identifier字段。查看System.pasLoadResString以了解 RTL 如何使用此信息。

您可以使用这些PResStringRec值在运行时构建一个TDictionary<string, PResStringRec>,然后使用该字典来实现GetNamedResourceString上面概述的假设功能。

NamedResources := TDictionary<string, PResStringRec>.Create;
NamedResources.Add('aabbcc', PResStringRec(@aabbcc));

function GetNamedResourceString(const Name: string): string;
begin
  Result := LoadResString(NamedResources[Name]);
end;

如果我是为一个真正的项目这样做,我可能会使用预构建脚本来解析输入文件,以自动生成对NamedResources.Add相应resourcestring声明的调用。

于 2015-03-19T17:11:01.693 回答
1

resourcestring被编译成一个字符串表资源。这些由数字标识符标识。编译器维护您声明的resourcestring实例和数字标识符之间的映射。当您访问 a 时resourcestring,编译器知道数字标识符,并发出使用该标识符的代码。本质上,您希望做的是能够从您的名称resourcestring和数字标识符进行映射。不幸的是,该地图仅在编译期间存在。它不包含在可执行文件中。

您唯一的其他希望是编译器为资源字符串生成 RTTI 信息。但是,它不会这样做,除非我非常错误。

鉴于这些限制,您将需要提出自己的机制来映射名称和资源字符串。一种可能性是避免使用内置的resourcestring,并通过您自己的机制管理字符串表资源及其标识符。

于 2015-03-19T13:26:15.643 回答