Nein geht nicht direkt.
Die einfachste Lösung ist es am Anfang des Strings selber eine Nummer zu speichern. Also so
Delphi-Quellcode:
resourcestring
sFehler = '123: Fehler bei XYZ aufgetreten';
Bei jedem Zugriff auf einen Resourcestring ist der String ein normaler LongString. Also zum Zeitpunkt wenn die
Exception diesen String übergeben bekommt ist es ein LongString und es existiert keine Verbindung mehr zu einer Resource. Das "Laden" der Resourcestrings macht der Laufzeitcode vollständig transparent. Also schon während der Laufzeit wurden die Resourcestring in LongString quasi geladen und konvertiert. Das macht der
RTL Code auf Anlass des Compilers zum Zeitpunk der Initialisierung einer
Unit, also bevor die Initialization Sektion der
Unit aufgerufen wird. Egal ob im Source auch Initialization steht oder nicht, eine
Unit hat diese "Initialization Funktion" immer. Und davor werden die Resourcestring real geladen in LongStrings.
Davon abgesehen gilt folgendes: Jeder String der als Resource gespeichert wurde bekommt eine eindeutige ID. Die Vergabe dieser ID macht der Linker vollständig transparent für uns. Dh. jedesmal nach der Deklaration eines neuen Resourcestrings ändern sich ALLE IDs dieser Strings in der Resource. Ein Resourcestring hat also aus Sicht des Programmieres in Delphi keine vorhersagebare und immer gleiche ID in der String-Resource der EXE.
Es gibt einen Weg, definitiv, aber der würde nahe an einem Hack liegen. Der
RTL Code der einen Resourcestring lädt muß ja selber wissen welche Resource-ID in der String-Resource der EXE diesem zugeordnet ist. Dazu speichert der Linker eine Tabelle zum Resourcestring ab in der eine Basis-ID drinnensteht. Man kann über Zeigerarithmetik an diese "Tabelle" rankommen und so auch an die IDs der Resourcestrings. Damit weist DU aber eben noch nicht welcher reale String, eg. Text, sich hinter dieser ID verbirgt. Kompiliert man neu so kann es durchaus sein das sich diese ID zum Text ändert.
[edit]
Schau mal in
Unit System.pas, da findest du
Delphi-Quellcode:
type
PResStringRec = ^TResStringRec;
TResStringRec = packed record
Module: ^Longint;
Identifier: Integer;
end;
procedure Test;
resourcestring
sTest = 'Test String Resource';
var
Msg: PResStringRec;
begin
Msg := @sTest;
ShowMessage(LoadResString(Msg));
end;
Der Resourcestring wird also als Zeiger vom Typ PResStringRec angesprochen, eg. konvertiert. Das Member .Indetifier enthält entwerder die reale Resource ID des zugehörigen Strings aus der Resource der EXE oder den LongString selber. Sollte .Identifier < $10000 sein, sprich das höherwertige Word des Cardinals = 0 sein, so ist es eine Resource ID. Der String muß dann aus der EXE geladen werden. Danach wird .Identifier aber als Zeiger eines LongString abgesprochen. Dh. beim Zugriff auf einen Resourcestring wird nur beim 1. mal der String aus der EXE geladen, danach steht er fertig im Speicher und wird nicht mehr nachgeladen.
Schau dir die Implementierung in
Unit System.pas von LoadResString() genauer an.
[/edit]
Gruß Hagen