2015-03-19 66 views
1

的情况找到一个资源名称是:德尔福如何从资源字符串单元

unit abc; 

interface 

resourcestring 
    aabbcc = 'my text here'; 

implementation 

end. 

从我的应用程序收到错误代码“为aabbcc”。有可能使用错误代码访问资源名称aabbcc?

+0

您的问题对我来说并不清楚,对不起,但请检查'PResStringRec(@aabbcc)^。Identifier'表达式对您有任何用处。 – 2015-03-19 22:24:23

回答

1

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

你唯一的希望是编译器生成资源字符串的RTTI信息。但是,除非我非常误解,否则它不会这样做。

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

3

我想象你要求具有以下签名和行为的函数:

function GetNamedResourceString(const Name: string): string; 

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

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

但是,一种方法,可以在代码中使用Delphi resourcestring标识符并发现其数字ID。键入表达式@aabbccPResStringRec,然后读取其Identifier字段。看看LoadResStringSystem.pas看看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; 

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

+0

好的迹象。谢谢。 – 2015-03-31 14:07:58

+0

感谢您的好路径。问题已解决。 – 2015-04-08 07:30:38