2015-03-19 64 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