Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Mehrsprachig mit Ini


chickenfigt1989 - Do 19.08.10 23:32
Titel: Mehrsprachig mit Ini
Hallo,
Ich wollt mein programm emhrsprachig machen.
Dabei dachte ich an ini.
Wie sollte den die ini aussehen?
zur info:
Ich hab über 100 formen und showmessage sollten auhc übersetzt werden
lg


elundril - Do 19.08.10 23:34

Am besten gar nicht auf Ini zurückgreifen. Ich würde vorschlagen XML, GNUGetText oder Ressourcen (ich glaub für die gibts n Tutorial sogar hier). Am besten mal alle Themen in der Forensuche suchen, das wurde schon n paar mal disskutiert afaik.

lg elundril


chickenfigt1989 - Fr 20.08.10 00:01

Würde es aber gern dennoch mit Ini machen da ich mit GNUGetText gar nicht zurecht komme.
lg


Webo - Fr 20.08.10 00:13

Ich würde mich dem Vorschlag anschließen und XML nehmen. Auch wenn es neu für dich ist. Denn: Nur Bekanntes anzuwenden ist doch auf Dauer auch langweilig, oder ?


elundril - Fr 20.08.10 00:24

Ich kann dir auch erklären warum XML einer INI vorzuziehen ist. Ein Formular kannst du nämlich sehen wie einen Baum, bei dem jede Komponente ein Blatt ist und jede Eigenschaft ein Blatt ist. Wobei Komponenten wieder Blätter haben können, so wie Formulare. Und das schöne ist, bei XML kannst du die Daten ebenfalls als Baum darstellen. Durch diese Ähnlichkeit kann man das viel bequemer modellieren und programmieren.

lg elundril


Xion - Fr 20.08.10 00:27

Mal zur Ini:

Ich würde die ini so aufbauen:

[Deutsch]
0-Speichern fehlgeschlagen
1-Meldung2
2-Meldung3

[English]
0-Saving failed
1-Message2
2-Message3


Dann wählst du in deinem Programm ne Sprache aus. Dann lädst du dir die passende Sprache in ein String Array. Jede Meldung kriegt eine Konstante. MSG_CannotSaveFile=0 z.B.

Und dann schreibst du immer ShowMessage( MessageList[MSG_CannotSaveFile] );

Du wirst natürlich nicht drum herum kommen, deine Forms von Hand zu übersetzen ;)


jaenicke - Fr 20.08.10 05:32

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
Ich kann dir auch erklären warum XML einer INI vorzuziehen ist.
Noch dazu sind die API-Funktionen, auf denen TIniFile aufbaut, als deprecated markiert, sollten also möglichst nicht mehr verwendet werden...
Eben weil das INI-Format noch ein Relikt aus den alten Windowsversionen ist, werden auch die entsprechenden Funktionen nur noch mitgeschleppt. Es kann aber passieren, dass es in einer der nächsten Windowsversionen diese Funktionen nicht mehr gibt. Und dann funktionieren auch alle Programme, die die nutzen, nicht mehr...


thepaine91 - Fr 20.08.10 09:38

Ich hätte eine Datenbank genommen. ^^


Critter - Fr 20.08.10 10:53

Hi,

user profile iconXion hat folgendes geschrieben Zum zitierten Posting springen:
[Deutsch]
0-Speichern fehlgeschlagen
1-Meldung2
2-Meldung3

[English]
0-Saving failed
1-Message2
2-Message3


davon würde ich abraten, ich würde mit mehreren Dateien Arbeiten - für jede Sprache eine. Das hat den Vorteil, dass die Dateien, die öffnen musst nicht so groß sind, und somit schneller geparst werden können - völlig unabhängig vom verwendeten Format (INI/XML/DB).
Desweiteren würde ich keine Nummernidizes nehmen, sondern den Text in einer Basissprache, bevorzugt Englisch, verwenden. Das hat den Vorteil, dass du dir deine Übersetzungsfunktion so gestalten kannst, dass sie wenn ein Text mal nicht in der Sprachdatei vorhanden ist immer noch den Index-Wert zurück liefern kann und somit den richtigen Text in Englischer Sprache. Du musst dich nur dran gewöhnen immer die gleichen Bezeichner zu Verwenden also. z. B. immer Einstellungen zu sagen und nciht mal Einstellungen und mal Optionen.

Des weiteren würde ich auch nicht darauf achten, wo der Text jetzt her kommt, also aus welchem Form. Wenn ein Button die Caption "Cancel" hat suchtst du einfach die allgemeine Übersetzung für Cancel und nicht die für den Cancel-Button in Form3, sonst produzierst du ziemlich viel Redundanten overhead und hasst viel mehr arbeit wenn sich mal ein Begriff ändern soll (also aus allen "Einstellungen" plötzlich "Optionen" werden sollen).

Wenn du nicht speichern musst, wo die Werte her kommen kannst du anstelle einer INI oder auch XML gleich eine reine Textdatei verwenden, wen du die dann noch ein wenig Optimierst (Nach Index sortieren und Texte dann Binär suchen oder ähnliches) kann das Auffinden der Texte darin auch recht Flott werden.

Ein Beisiel für German.lng:

Quelltext
1:
2:
3:
4:
5:
Cancel=Abbrechen
Ok=Ok
Options=Einstellungen
Sorry, you are out of Memory!=Ey alter dein Speicher ist voll!
The entered value (%1) is bigger than %2=Der eingegebene Wert darf nicht größer als %2 sein. Sie haben aber %1 eingegeben.


critter

PS: Wenn du tatsächlich so eine Dateistrucktur wählst, lässt sie sich auch hervorragend, in einer tStringList verwalten ;).


Gausi - Fr 20.08.10 11:12

Wenn du 100 Forman hast und dementsprechend vermutlich tausende Strings, dann würde ich dir dringend von so einer selbstgebastelten Ini/XML/Sonstwas-Lösung abraten. Mal abgesehen davon, dass vermutlich 90 der 100 Formen überflüssig sind, weil da ein dicker Design-Fehler in der Software steckt. :nixweiss:

Bei GetText hast du dann zum Übersetzen eine Zeile Code, und das ist fast beliebig erweiterbar. Auch die Pflege der Übersetzungen ist recht einfach, wenn man das einmal raushat. :)


Hidden - Fr 20.08.10 12:51

Ähm, gab es nicht eine Unit von(jetzt verwechsle ich ihn wieder mit jemandem >.<).. user profile iconNarses, um seine Programme mehrsprachig zu gestalten?

lg,


jaenicke - Fr 20.08.10 16:13

Das war user profile iconAXMD, aber die Unit müsste ich erst suchen, keine Ahnung wie die hieß, ist schon 4 oder 5 Jahre her. Ich schau nach der Arbeit mal.


delfiphan - Fr 20.08.10 20:47

"100 Forms" -> es gibt kommerzielle Lösungen dafür. Z.B. Korzh Localizer.


jaenicke - Fr 20.08.10 20:50

Delphi selbst hat ja auch eine integrierte Lösung dafür, die funktioniert auch recht gut. Insbesondere weil es bei so vielen Forms recht gut automatisiert.

Hier ist die Unit, die ich vorhin meinte:
http://www.delphi-forum.de/viewtopic.php?t=38632&highlight=language


Hidden - Fr 20.08.10 21:05

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das war user profile iconAXMD
My -.-

Die "in Delphi integrierte Lösung" interessiert mich jetzt gerade, ist unter Project\Languages\Add versteckt. :lupe:

lg,


chickenfigt1989 - Fr 20.08.10 23:05

Oke hab mir mal den integrierten übersetzer von delphi angeschaut, aber wie soll der Funktionieren?
wenn ich die gewünschte Sprache hinzufüge wird ne kopie meiner Formen in nen ENG ordner angelegt aber da is nichts übersetzt.
lg


elundril - Fr 20.08.10 23:09

Na, übersetzen musst du es vermutlich selbst noch. So wie bei INI oder XML oder den anderen Systemen...


Tranx - Sa 21.08.10 16:43

Ich hätte da eine Idee, klingt sicher nicht besonders professionell, aber funktuioniert.

Angenommen, Du hast eine TEdit-Komponente, die die Sprache beinhaltet z.B. "Deutsch" oder eine Combobox-Komponente mit mehreren Sprachtexten. Dann wäre es sinnvoll, alle Komponenten des Formulars mit ihren Caption-Eigenschaften in eine Inidatei zu schreiben bzw. bei Wechsel der Sprache aus dieser wieder auszulesen.

z.b.:

Speichern, bzw. Laden


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:
procedure Sprachversion(speichern : boolean);
var
   i : integer;
   c : TComponent;
begin
   Inidatei := TInifile.Create(Pfad+Name+Spracherw+Endung);
   if speichern then with Inidatei do begin
     with Formular do begin
       for i := 0 to ComponentCount-1 do begin
   c := Components[i];
         CName := c.Name;
         if c is TWinControl then begin
           WriteString('CAPTION',CName,TWinControl(c).Caption);
           WriteString('HINT',CName,TWinControl(c).Hint);
         end;
       end;
     end;
   end else begin
     with Formular do begin
       for i := 0 to ComponentCount-1 do begin
         c := Components[i];
         CName := c.Name;
         if c is TWinControl then begin
           TWinControl(c).Caption := ReadString('CAPTION',CName,'');
           TWinControl(c).Hint := ReadString('HINT',CName,'');
         end;
       end;
     end;
   end;
   free;
end;


Pfad + Name + Spracherw + Endung: z.B.: Paramstr(0)+'SPRACHE_'+'DEU'+'.TXT';

Dann ist die "IniDatei" im Programmverzeichnis. Du brauchst dann nur die andere Sprachdateien zu erzeugen.


Ich habe dies jetzt nicht getestet, aber es sollte funktionieren.

Ich hoffe, ich habe Dir gedient.

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


jaenicke - Sa 21.08.10 17:38

Und wo ist der große Unterschied zu der fertigen Unit, die bereits angesprochen und von mir verlinkt wurde? :gruebel:


Fienix - Sa 21.08.10 19:03

Ich hab es auch so gemacht wie von user profile iconTranx beschrieben.
Ich lade allerdings beim Pogrammstart eine TStringList, die om OnShow/OnAfterShow(mein Ereignis) auch wieder mit Captions gefüllt wird die noch nicht in der INI/XML vorhanden sind.
Wenn was neues dazu kommt dann wird meine TStringList erweitert und beim FormClose in die Datei geschrieben.


elundril - Sa 21.08.10 20:54

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Und wo ist der große Unterschied zu der fertigen Unit, die bereits angesprochen und von mir verlinkt wurde? :gruebel:


Das nicht geprüft wird ob die betreffende Komponente überhaupt Caption und Hint hat. ;)

lg elundril