Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Ini als Sprachdatei nutzen ? (https://www.delphipraxis.net/161205-ini-als-sprachdatei-nutzen.html)

Blamaster 22. Jun 2011 14:37

Ini als Sprachdatei nutzen ?
 
Hi,

ich möchte ein Programm in verschiedene Sprachen übersetzen.

Mir ist dabei vorallem wichtig, dass mit Sprachfiles gearbeitet wird und auch user die Möglichkeit haben selber Sprachfiles anzulegen.

Daher erscheint es mir als naheliegend ini Datei zu nutzen.

Ich habe mal ein Programm gesehen, welches die Sprachfiles nach folgendem Schema aufbaut:

[Deutsch]
New=Neu
Open=Öffnen
Save=Speichern
Done=Fertig

Es werden also keine Objectnamen oder Indexwerte gespeichert, sondern lediglich der wirkliche Übersetzungstext wie bei einem Wörterbuch.

Gibt es dafür Umsetzungsbeispiele ?

Ich stelle mir das so vor:
- Beschriftung im Programm auf Englisch
- Programm durchläuft automatisch Objekte und sucht nach übersetzung, wenn keine Übersetzung gefunden original Beschriftung beibehalten

Gruß Yannic

CCRDude 22. Jun 2011 14:42

AW: Ini als Sprachdatei nutzen ?
 
Als Key macht es eher Sinn, den Namen der Controls zu verwenden, als den aktuellen Text. Als grober Anhaltspunkt:
Code:
for i := 0 to Pred(Form.ComponentCount) do begin
   if (Form.Components[i] is TControl) then begin
      if (Form.Components[i] as TControl).Parent = Form then begin
         ReadControl(Form.Name, (Form.Components[i] as TControl), i);
      end;
   end else if (Form.Components[i] is TMenu) then begin
      ReadMenuItem(Form.Name + '.' + (Form.Components[i] as TMenu).Name, (Form.Components[i] as TMenu).Items);
   end else if (Form.Components[i] is TActionList) then begin
      ReadAction(Form.Name + '.' + (Form.Components[i] as TActionList).Name, (Form.Components[i] as TActionList));
   end;
end;
ReadControl muss dann, falls es ein TWinControl ist, über dessen ControlCount wieder alle seine Controls durchgehen.

Wenn die Controls alle ordentlich und sinnvoll benannt sind, ist das genauso anwenderfreundlich; aber ob Du in den einzelnen Untermethoden nun .Caption/.Text oder .Name als Key verwendest, ist ja nur ein winziger Unterschied.

Satty67 22. Jun 2011 14:42

AW: Ini als Sprachdatei nutzen ?
 
Ich hatte es bei einem Programm mal ähnlich, aber als Stringliste mit dem Schema:

Button1=OK
Button2=Cancel

usw.

Damit konnte ich direkt in Components suchen und ersetzen.

(Mist, um Sekunden zu langsam...)

€: Button1/2 nur als Beispiel, sinnvolle Benennung ist da natürlich Pflicht.

Blamaster 22. Jun 2011 15:02

AW: Ini als Sprachdatei nutzen ?
 
Zitat:

Button1=OK
Button2=Cancel
Mit den Namen zu arbeiten halte ich aber für extrem redundant. Ein Programm mit 10 Okay Buttons hat dann 10 Einträge in der ini.

Gausi 22. Jun 2011 15:07

AW: Ini als Sprachdatei nutzen ?
 
Schau dir mal GetText an. Die arbeitet auch mit Sprachdateien, und andere Nutzer können recht einfach eigene Übersetzungen anfertigen. Und da hat man noch einige andere Funktionen, wie z.B. das Auslesen aller Strings aus den pas und dfm-Dateien, um eine entsprechende Rohdatei für Übersetzungen zu erzeugen. :)

Namenloser 22. Jun 2011 15:12

AW: Ini als Sprachdatei nutzen ?
 
Zitat:

Zitat von Gausi (Beitrag 1107720)
Schau dir mal GetText an. Die arbeitet auch mit Sprachdateien, und andere Nutzer können recht einfach eigene Übersetzungen anfertigen. Und da hat man noch einige andere Funktionen, wie z.B. das Auslesen aller Strings aus den pas und dfm-Dateien, um eine entsprechende Rohdatei für Übersetzungen zu erzeugen. :)

Wollte ich auch gerade vorschlagen. Man muss das Rad hier wirklich nicht neu erfinden ;)

Satty67 22. Jun 2011 16:38

AW: Ini als Sprachdatei nutzen ?
 
Zitat:

Zitat von Blamaster (Beitrag 1107719)
Zitat:

Button1=OK
Button2=Cancel
Mit den Namen zu arbeiten halte ich aber für extrem redundant. Ein Programm mit 10 Okay Buttons hat dann 10 Einträge in der ini.

Nein, denn der OK Button auf jedem Formular hat immer den Namen ButtonOK (10 OK-Button auf einem Formular schließe ich jetzt mal als unwahrscheinlich aus) ;)

Aber vielleicht ist der Vorschlag, vorhandene Übersetzungssysteme zu nutzen, letzlich besser.

Blamaster 22. Jun 2011 22:33

AW: Ini als Sprachdatei nutzen ?
 
Hi,

ich habe nun ein wenig mit GetText gepielt.

Allerdings wird mir da etwas noch nicht so ganz klar. Kann der User selber wählen, welche Sprache er nutzen möchte, oder wird das Programm automatisch an die System Sprache angeglichen ?

Welche Möglichkeiten habe ich das Sprachfile selber zu testen ?

Gruß Yannic

Wishmaster 23. Jun 2011 04:53

AW: Ini als Sprachdatei nutzen ?
 
Hi

ich benutze XML für die Sprach und Programm Einstellungen
dabei kannst du all sprachen in die selbe Datei stecken wen du willst.

Delphi-Quellcode:
unit Language_Classe;

interface
 uses SysUtils, NativeXml;


Function Language_Load_File(const FileName : String) : Boolean;
Function Language_UnLoad_File() : Boolean;
Function Language_Loaded(): boolean;
Function Language_Get_Text(LangID : UTF8String; LangName : UnicodeString) : Widestring;



implementation

var LanguageFile : TNativeXml;
    Loaded : boolean = false;

(***************************** Load Language File *****************************)

Function Language_Load_File(const FileName : String) : Boolean;
begin
  Result:= false;

 if not FileExists(FileName) then
  exit;

 if Loaded then
  begin
   if (Assigned(LanguageFile)) then
    begin
     FreeAndNil(LanguageFile);
     Loaded:= false;
    end;
  end;


 try
   LanguageFile:= TNativeXml.CreateName('Language');
   LanguageFile.LoadFromFile(Filename);
  if (Assigned(LanguageFile)) then
   begin
    Loaded:= true;
    Result:= true;
   end;
 except //  Could not load the language file'
   on E: Exception do
    begin
     if (Assigned(LanguageFile)) then
      FreeAndNil(LanguageFile);
      Loaded:= false;
      Result:= false;
      Exit;
    end;
 end;
end;

(**************************** UnLoad Language File ****************************)

Function Language_UnLoad_File() : Boolean;
begin
  Result:= false;

 if Loaded then
  begin
  if (Assigned(LanguageFile)) then
   begin
    FreeAndNil(LanguageFile);
    Result:= true;
    Loaded:= false;
   end;
  end;
end;

(*************************** IsLoadded Language File **************************)

Function Language_Loaded(): boolean;
begin
  Result:= Loaded;
end;

(***************************** Load Language File *****************************)
(*
  NodeByName('LangID').ReadString('ID_INF_0001=');
  NodeByName('LangID').ReadString('ID_OBJ_0001=');
*)

Function Language_Get_Text(LangID : UTF8String; LangName : UnicodeString) : Widestring;
var Str : Widestring;
begin
   Result:= '';

 if Loaded then
  begin
   With LanguageFile.Root do
    begin
      Str:= NodeByName(LangID).ReadUnicodeString(LangName);
     if (Trim(Str) = '') or (Length(Str) = 0) then
      Result:= ''
     else
      Result:= Str;
    end;
  end;
end;


end.
Code:
<?xml version="1.0" encoding="UTF-16"?>
<Language>
  <Info>
    <ID_INF_0001=>Wishmaster</ID_INF_0001=>
    <ID_INF_0002=>1.0</ID_INF_0002=>
    <ID_INF_0003=>support@blabla.com</ID_INF_0003=>
    <ID_INF_0004=>User</ID_INF_0004=>
    <ID_INF_0005=>User</ID_INF_0005=>
  </Info>
  <LangID>
   <!-- Mein Form -->
    <ID_OBJ_0001=>Drive</ID_OBJ_0001=>
    <ID_OBJ_0002=>Drive Action</ID_OBJ_0002=>
    <ID_OBJ_0003=>Close</ID_OBJ_0003=>
    <ID_OBJ_0004=>Eject</ID_OBJ_0004=>
    <ID_OBJ_0005=>Lock</ID_OBJ_0005=>
    <ID_OBJ_0006=>Unlock</ID_OBJ_0006=>
    <ID_OBJ_0007=>CDDB</ID_OBJ_0007=>   
    <ID_OBJ_0008=>Read CD-Text</ID_OBJ_0008=>   
    <ID_OBJ_0009=>Read Remote freedb</ID_OBJ_0009=>
    <ID_OBJ_0010=>Read From CD Player.ini</ID_OBJ_0010=>


     blablabla

Teekeks 23. Jun 2011 10:54

AW: Ini als Sprachdatei nutzen ?
 
Also ich nutze Ini-Dateien zum Speichern.
Und zwar im sinne von
Code:
[Lang]
Hallo=Hello
Öffnen=Open
Die Datei heißt dann en.lang.
Geladen wird nach <sprache>.lang

Mehrere Dateien sind es um möglichst schnell die Sprachen laden zu können.

Daniela.S 23. Jun 2011 11:22

AW: Ini als Sprachdatei nutzen ?
 
Ich verwende eine kleine Datenbank, die die Sprachübersetzungen beinhaltet. In der werden auch sonstige Sprachrelevanten Dinge gespeichert. Eventuell gibt es auch Bilder, die Sprachabhängig sind, oder je nach Land (Flaggen, Fotos oder Maps von Niederlassungen usw.) müssen bestimmte Daten aufgenommen werden.

Du kannst eine Tabelle für jedes Formular erstellen. Hier reichen zwei Felder, eines mit dem Schlüssel, das andere mit dem Wert. zB. "btnOK", "OK". Ich würde unbedingt den Namen des Objektes nehmen, anstatt den Text.

Und die Texte der Dialoge nicht vergessen...

Blamaster 23. Jun 2011 22:38

AW: Ini als Sprachdatei nutzen ?
 
Hi,

ich nutze jetzt GNU GetText.

Die Frage mit dem Sprache laden konnte ich mir nun selber beantworten (UseLanguage('en'))

Nun sind mir aber ein paar Sachen noch nicht ganz klar.

Ich weiß zwar das man bei der Übersetzung Objekte ignorieren kann, aber gibt es auch eine Möglichkeit, dass man auch manche Forms davon ausschließt variablen in die Übersetzungsdatei abzugeben ?

Wenn ich die Übersetzungsdatei erstellen lasse werden wirklich alle Strings in die Datei aufgenommen. Einige Buttons möchte ich beispielsweise garnicht übersetzen lassen, dennoch tauchen sie in der Übersetzungsdatei aus was wirklich nervt (Das gleiche gilt auch für Filemasken usw.)

Und schließlich noch ein Problem. Wenn ich im Code einer String variable einen zusammengesetzen String habe wie:

Delphi-Quellcode:
variable := 'Sie haben Datei: ' + Dateiname + ' gewählt. Die Datei ist: ' Size + ' MB groß';
Nun kann ich die einzelnen Teilstrings als Resorcen strings anlegen sprich:

Delphi-Quellcode:
variable := _('Sie haben Datei: ') + Dateiname + _(' gewählt. Die Datei ist: ') Size + _(' MB groß');
Nun wir logischerweise in der Übersetzungsdatei folgendes aufgenommen:
Sie haben Datei:
gewählt. Die Datei ist:
MB groß

Durch diese Teilstrings lässt sich eventuell kein sinvoll übersetzter Satz mehr aufbauen. Wie kann man das lösen ?

Gruß Yannic

Satty67 23. Jun 2011 22:53

AW: Ini als Sprachdatei nutzen ?
 
zumindest für das zweite Problem gibt es einen Weg
Zitat:

Zitat von Blamaster (Beitrag 1108001)
Delphi-Quellcode:
variable := 'Sie haben Datei: ' + Dateiname + ' gewählt. Die Datei ist: ' Size + ' MB groß';

wenn es noch nicht zu viel von den Konstrukten gibt, dann umschreiben in

Delphi-Quellcode:
variable := Format('Sie haben Datei: %s gewählt. Die Datei ist: %d MB groß', [Dateiname, Size]);

Blamaster 24. Jun 2011 12:10

AW: Ini als Sprachdatei nutzen ?
 
Hi,

super damit ist das zweit problem schonmal gelöst :)

Gruß Yannic

Edit.

und nochmal eine Frage. Wenn sich nun im Programm sachen ändern und manche Übersetzungstexte daher nicht mehr nötig sind, gibt es dann eine Möglichkeit Einträge aus der po wieder zu löschen ? Beim mergen werden nur neue aufgenommen aber veraltete nicht gelöscht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:19 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