![]() |
Delphi-Version: XE
Einen resourcestring über einen String ansprechen
Folgender Code(Schnipsel) ist vorhanden:
Delphi-Quellcode:
Ich möchte über eine Funktion den Wert auslesen und als String den Bezeichner übergeben.
resourcestring
AA_10_10='Dies ist ein Text'; AA_10_11='Dies ist ein weiterer Text'; AA_10_12='Dies ist noch ein Text'; AA_10_13='Dies ist der letzte Text';
Delphi-Quellcode:
LabelXy.caption sollte dan 'Dies ist ein Text' anzeigen.
LabelXy.caption:=constantentext('AA_10_10');
Jemand eine Idee, wie ich das realsisieren kann? |
AW: Einen resourcestring über einen String ansprechen
Geht nicht.
- Eine Resourcestring wird in den Resourcen als durchnummerierte Gruppen zu je 16 Strings abgelegt. - Die Nummern/Indize der Resourcestrings werden bei jedem Neucompilieren "zufällig" (vermutlich in Compilier-/Linkreihenfolge) neu vergeben. - Delphi speichert keine Variablen-/Konstantennamen. > Erstell einfach mal eine EXE, mit deinen Ressourcestrings und schau mit einem Resourceeditor dort rein. Lösung: Selber die namentlichen "Text"-Resourcen erstellen (keine nummerierten Stringlisten, es sei denn du willst über die selbstvergebenen Nummern/Indize zugreifen) |
AW: Einen resourcestring über einen String ansprechen
Zitat:
Code:
resourcestring
AA_10_10='Dies ist ein Text'; AA_10_11='Dies ist ein weiterer Text'; AA_10_12='Dies ist noch ein Text'; AA_10_13='Dies ist der letzte Text'; var ResStr: Array [0..3] of string =(AA_10_10,AA_10_11,AA_10_12,AA_10_13); Function constantentext(i: word): String; begin result:=ResStr[i] ; end; procedure TForm1.Button1Click(Sender: TObject); begin Label1.caption:=constantentext(random(3)); // oder einfach nur (ohne spez.Function constantentext) : Label1.caption:=ResStr[random(3)]; end; |
AW: Einen resourcestring über einen String ansprechen
@himitsu: Danke für die Info. Ich habe es befürchtet :-(
@ASM: Das wird mir nichts bringen. Ich möchte ja speziell über den Namen der Konstante auf den Inhalt zugreifen und nicht über eine (nichtssagende) Indexnummer. Letztendlich werde ich auf ca. 50.000 verschiedene Strings zugreifen müssen. Dazu setze ich mir den Namen aus einer Berechung als String zusammen (AA_10_10 sind z.B. 3 zusammengesetzte Teilbereiche) und über diesen Namen Greife ich auf den Ressourcenstring zu. |
AW: Einen resourcestring über einen String ansprechen
Bei 50.000 Resourcenstrings würde sich ja schon eher eine alternative Methode anbieten, wie eine Datenbank oder zumindest eine Key/Value Stringlist aus einer Text/XML-Datei.
Da wäre dann wenigsten auf einen Schlag die gewünschte Zugriffslogik ein Kinderspiel. |
AW: Einen resourcestring über einen String ansprechen
Ich fand es bisher immer gut, daß diese Daten in der EXE-Datei vorhanden waren. Eine externe Datei kommt für mich erst mal nicht in Frage.
Bisher hatte ich alle Strings in eine Procedure gepackt. Aber mit DelphiXE gibt's nun ein Problem. Siehe: ![]() Jetzt muss ich mir was anderes einfallen lassen. |
AW: Einen resourcestring über einen String ansprechen
Du kannst die XML Datei auch als Ressource in deine Exe eincompilieren und zur Laufzeit dann auf der Festplatte speichern. Ich würde sie dann in das temporäre Verzeichnis entpacken, denn da hast du auf alle Fälle Schreibrechte. Aber bitte bei Beendigung des Programms auch wieder löschen. Oder du erstellst ein Setup.
|
AW: Einen resourcestring über einen String ansprechen
Zitat:
Danke:thumb: |
AW: Einen resourcestring über einen String ansprechen
TResourceStream --> TStringStream --> xmldoc.loadXml ;-)
|
AW: Einen resourcestring über einen String ansprechen
Alternative ohne Verwendung eines externen Files zur Runtime
(in Anlehung an Julian M.Bucknall, 2001, "Tomes of Delphi: Algorithms and Data Structures"): File ResStrings.inc:
Code:
Resourcefile:
CONST
cResStrBase = $5444; maxResCount = 12; AA_10_10 = cResStrBase + 0; AA_10_11 = cResStrBase + 1; AA_10_12 = cResStrBase + 2; AA_10_13 = cResStrBase + 3; AA_11_10 = cResStrBase + 4; AA_11_11 = cResStrBase + 5; AA_11_12 = cResStrBase + 6; AA_11_13 = cResStrBase + 7; AA_12_10 = cResStrBase + 8; AA_12_11 = cResStrBase + 9; AA_12_12 = cResStrBase + 10; AA_12_13 = cResStrBase + 11; {..usw..}
Code:
Compile Resource:
#include "ResStrings.inc"
STRINGTABLE BEGIN AA_10_10, "Dies ist ein Text zu (10_10)" AA_10_11, "Dies ist ein Text zu (10_11)" AA_10_12, "Dies ist ein Text zu (10_12)" AA_10_13, "Dies ist ein Text zu (10_13)" AA_11_10 "Dies ist ein Text zu (11_10)" AA_11_11 "Dies ist ein Text zu (11_11)" AA_11_12 "Dies ist ein Text zu (11_12)" AA_11_13 "Dies ist ein Text zu (11_13)" AA_12_10 "Dies ist ein Text zu (12_10)" AA_12_11 "Dies ist ein Text zu (12_11)" AA_12_12 "Dies ist ein Text zu (12_12)" AA_12_13 "Dies ist ein Text zu (12_13)" {..usw..} END
Code:
Projektfile:
brcc32.exe ResStrings.rc
Code:
Da zur Compiletime die Logik der in der Stringtable vergebenen Indexkonstanten feststeht, muss allein die Zuordung der Namen dieser Indexkonstanten zu den Strings des entspr. Arrays mit Hilfe einer Funktion PrepareArray() ausgearbeitet werden.
{...}
implementation {$R *.dfm} {$R ResStrings.res} {$I ResStrings.inc} type tArrResStr = array of string; var ArrResStr: tArrResStr; // an die Logik der Bezeichnung der Elemente des Arrays anpassen ! // hier zum konkreten Beispiel der verwendeten Stringtable procedure PrepareArray(var Arr: tArrResStr); var i, j, z, basis: integer; begin setlength(Arr, maxResCount); basis := 10; z := basis; j := 0; for i := Low(Arr) to High(Arr) do begin case i of 0: ; 4: begin inc(z, 1); j := 0; end; 8: begin inc(z, 1); j := 0; end; {...} else inc(j); end; Arr[i] := format('AA_%2.d_%2.d', [z, basis + j]); end; end; procedure ClearArray(var Arr: tArrResStr); begin setlength(Arr, 0); end; function IndexOf(Arr: tArrResStr; const item: string): Integer; var i: Integer; begin Result := -1; for i := Low(Arr) to High(Arr) do begin if AnsiSameText(item, Arr[i]) then begin Result := i; Break; end; end; end; function constantentext(ResConst: word): string; overload; begin setlength(result, 255); LoadString(hinstance, ResConst, pchar(result), 255); end; function constantentext(ResConstName: string): string; overload; var ResConst: Word; begin ResConst := IndexOf(ArrResStr, ResConstName); result := pchar(constantentext(cResStrBase + ResConst)); end; procedure TForm1.Button1Click(Sender: TObject); begin PrepareArray(ArrResStr); // Beispiel der Übergabe per Indexkonstante als String Label1.caption := constantentext('AA_10_10'); Label2.caption := constantentext('AA_11_13'); // Beispiel der Übergabe unmittelbar als Indexkonstante Label3.caption := constantentext(AA_12_12); ClearArray(ArrResStr); end; Dies ist die eigentliche Aufgabe der Anpassung an das konkrete Projekt. Jedoch dürfte die Ausarbeitung dieser Funktion wohl keine ernsthaften Probleme machen, wenn die Namen der Indexkonstanten nach einem logischen Prinzip vergeben werden, welches dann wiederum in dieser Funktion umgesetzt wird. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz