情况是:
unit abc;
interface
resourcestring
aabbcc = 'my text here';
implementation
end.
从我的应用程序中收到错误代码'aabbcc'。是否可以使用错误代码访问资源名称aabbcc?
答案 0 :(得分:3)
我想你会要求一个具有以下签名和行为的函数:
function GetNamedResourceString(const Name: string): string;
Assert(GetNamedResourceString('aabbcc') = 'my text here');
资源字符串存储在程序中的字符串表资源中,其中每个字符串都有一个数字索引。您在程序中使用的命名标识符不会在运行时保留在任何位置。因此,没有内置的方法来获取文本'aabbcc'
并发现它与之关联的字符串资源。
但是, 是一种在代码中使用Delphi resourcestring
标识符并发现其数字ID的方法。将表达式@aabbcc
键入到PResStringRec
,然后阅读其Identifier
字段。查看 System.pas 中的LoadResString
,了解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
的调用。
答案 1 :(得分:1)
您的resourcestring
被编译为字符串表资源。这些由数字标识符标识。编译器在声明的resourcestring
实例和数字标识符之间维护一个映射。当您访问resourcestring
时,编译器知道数字标识符,并发出使用该标识符的代码。基本上您希望能够从resourcestring
的名称和数字标识符进行映射。不幸的是,该映射仅在编译期间存在。它不包含在可执行文件中。
您唯一的另一个希望是编译器为资源字符串生成RTTI信息。但是,它不会这样做,除非我非常错误。
鉴于这些限制,您需要提供自己的机制来在名称和资源字符串之间进行映射。一种可能性是避免使用内置的resourcestring
,并通过您自己的机制管理字符串表资源及其标识符。