Autor Beitrag
obbschtkuche
Gast
Erhaltene Danke: 1



BeitragVerfasst: Sa 20.09.03 13:37 
Hi.
Dieses Tutorial stellt die Möglichkeit vor, wie man Strings von Komponenten in Programmen ersetzen kann, ohne dies im Quelltext zu tun.

Als erstes müssen die Units "TypInfo" und "IniFiles" eingebunden werden

ausblenden Delphi-Quelltext
1:
2:
uses
 {...}, IniFiles, TypInfo;


Jetzt folgen ein paar Methoden:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
function GetStringProps(instance: TObject): TStringArray;
var
 j: integer;
 x: TPropList;
begin
 j:= GetPropList(PTypeInfo(TButton.ClassInfo), [tkString, tkWChar, tkLString, tkWString], @x, false);
 setlength(result, j);
 for j := 0 to length(result)-1 do result[j] := x[j].Name;
end;

function IsPropAvailable(instance: TObject; name: string): boolean;
var
 x: tPropList;
 i,j: integer;
begin
 result := false;
 j:= GetPropList(PTypeInfo(instance.ClassInfo), [tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,
    tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString, 
    tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray], @x, false);
 for i := 0 to j-1 do  
  if uppercase(x[i].Name) = uppercase(name) then
  begin  
   result := true;
   exit;
  end
end;

function SetPropertySave(instance: TObject; prop: string; value: variant): boolean;
begin
 result := true;
 if IsPropAvailable(instance, prop) then
  SetPropValue(instance, prop, value)
 else
  result := false; 
end;

procedure SetStringProps(form: TForm; ininame: string; Section: string);
var
 f: TIniFile;
 i,j: integer;
 stringprops: TStringArray;
begin
 f := TIniFile.Create(ininame);
 with form do
 begin
  if f.SectionExists(Section+'.'+name) then
  begin
   stringprops := GetStringProps(form);
   for j := 0 to high(stringprops) do
   begin
    if f.ValueExists(Section+'.'+name,stringprops[j]) then
     SetPropertySave(form, stringprops[j], f.ReadString(Section+'.'+name,stringprops[j],''))
   end;
  end;

  for i := 0 to componentcount-1 do
   if f.SectionExists(Section+'.'+components[i].name) then
   begin
    stringprops := GetStringProps(Components[i]);
    for j := 0 to high(stringprops) do
    begin
     if f.ValueExists(Section+'.'+Components[i].name,stringprops[j]) then
      SetPropertySave(Components[i], stringprops[j], f.ReadString(Section+'.'+Components[i].name,stringprops[j],''))
    end;
   end;
 end;
 f.Free;
end;


Die Procedure SetStringProps erwartet ein Formular, den Pfad zu einer Ini-Datei, in der die Texte gespeichert werden und den Namen einer Section.
Aufgerufen werden kann sie etwa so:

ausblenden Delphi-Quelltext
1:
2:
3:
 SetStringProps(self, 'C:\test.ini''Englisch');
// oder
 SetStringProps(self, 'C:\test.ini''Deutsch');


Der Aufbau der Inidatei ist folgendermaßen:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
[Deutsch.Form1]
Caption=Dies ist ein Test.
[Deutsch.Button1]
Caption=Deutsch.
[Deutsch.Button2]
Caption=Englisch.

[Englisch.Form1]
Caption=This is a Test.
[Englisch.Button1]
Caption=German.
[Englisch.Button2]
Caption=English.


Andere Eigenschaften wie z.B. Hint können auch gesetzt werden. (Es müssen allerdings Strings sein)
lkz633
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 136

WinXP, Suse Linux 8.2 (unter VMWare)
D7 Prof, K3 Prof
BeitragVerfasst: Do 17.06.04 23:08 
Hallo,

dieser Ansatz gefällt mir sehr gut, haette aber dazu noch ein Frage.

Wie übersetzt du Strings in z.B showmessage etc. ?

Danke und Gruss
lkz633
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Do 17.06.04 23:34 
Na, da wird man eben "von Hand" übersetzen müssen. Ich mach das meist so, daß ich sämtliche Texte in einer anderen Unit als Variablen definiere, die ich dann für jede Sprache dementsprechend bestücke. Anstelle von "ShowMessage('Division durch Null!')" also "ShowMessage(Str_ErrorDivZero)". Da wird dann auch häufig die Funktion Format sehr sinnvoll.

@Obbschtkuche:
Was ist, wenn ich zwei Buttons mit dem gleichen Namen auf unterschiedlichen Formularen habe? Müsste der Formularname nicht noch bei den einzelnen Komponenten als Identifikation einfliessen?

Cu,
Udontknow
obbschtkuche
Gast
Erhaltene Danke: 1



BeitragVerfasst: So 20.06.04 19:27 
Hmm, ist schon was länger her dass ich das gemacht habe, aber man könnte das ja über form.Name noch einbauen.