Tutorial-Dialoge mit deutschsprachigen Schaltern

Verweis: InputBox InputQuery ShowMessage
Uses: translations
Eingabe: TranslateUnitResourceStrings(Bezeichnung und Pfad)
Ausgabe: Dialoge und Meldungen in angegebener Sprache
Funktion: Übersetzung der Schalter.

Beispiel 1

Vorbereitung: Erstellen sie eine IDE Anwendung und ziehen Sie einen TButton auf die Form. Binden Sie die Unit: translations mit der Uses-Klausel in die Anwendung ein.

procedure TForm1.Button1Click(Sender: TObject);
var
  SchalterWahl: integer;
begin
  //Schalter nach deutsch
  TranslateUnitResourceStrings('LCLStrConsts',
    'C:\lazarus\lcl\languages\lclstrconsts.de.po');
  SchalterWahl := MessageDlg('Jetzt haben wir Schalter auf deutsch. ' +
    'Wollen Sie Schalter auf russisch?', mtConfirmation, mbYesNo, 0);
  // Bei nein beenden von klick
  if SchalterWahl = mrNo then Exit;
  //Schalter nach russisch
  TranslateUnitResourceStrings('LCLStrConsts',
    'C:\lazarus\lcl\languages\lclstrconsts.ru.po');
  SchalterWahl := MessageDlg('Wie gewünscht,Schalter auf russisch.', mtInformation,
    mbYesNo, 0);
end;

In dem Beispiel 1 haben wir einmal ein Fenster auf deutsch

Schalter und Überschrift auf deutsch.
Ja und Nein Lazarus kann auch deutsch wenn es will. 🙂

und wenn gewünscht auf russisch.

MessageDlg
Schalter und Überschrift auf russisch.
Auf russisch,… hoffe ich.

Selbst die Überschriften werden mit übersetzt. Die Eingegebene Mitteilung von uns bleibt natürlich auf deutsch. In der Unit Translations befindet sich der Befehl: „TranslateUnitResourceStrings“ Dieser Befehl weist dem Compiler an , dass er doch bitte eine Übersetzungsdatei mit dem Namen: „LCLStrConsts“ laden soll. Der zweite Parameter in dem Befehl ist die passende Datei mit einem passenden Pfad. Dieser Pfad ist bei mir: “C:\lazarus\lcl\languages\“ Versuche, einen relativen Pfad anzugeben führten bei mir zu keinem akzeptablen Ergebnis. (Windows 10 ?)
Wie dem auch sei, dieses Verzeichnis ist der Pfad an dem die Übersetzungen für den Compiler von Lazarus liegen. Bitte nicht mit dem Anderen „Languages“-Ordner verwechseln. Dieser liegt bei mir bei „C:\lazarus\languages\“. Dieser Ordner beinhaltet die komplette Übersetzung von der Lazarus IDE. Dies benötigen wir auf keinen Fall. Wir benötigen also die Dateien aus dem „lcl\languages“ – Ordner.

Ausschnit aus dem Verzeichnis: C:\lazarus\lcl\languages\

Wie wir sehen befindet sich außer der „lclstrconsts.de.po“ und der
lclstrconsts.ru.po“ noch andere Dateien. Die Struktur des Dateinamens hat folgende Logik:

Name der Datei: lclstrconsts
Eingabe: TranslateUnitResourceStrings(Bezeichnung und Pfad)
Sprache der Datei: ru für russisch, de für deutsch
Endung der Datei: Immer po, das Suffix wird benötigt um ein anderes Programm für die Bearbeitung der Datei zu laden.

In dem Verzeichnis befinden sich noch mehr Dateien die alle die gleiche Syntax haben. Da ist dann fr für französisch oder it für italienisch. Jetzt gibt es aber auch gleich erst einmal einen Wermutstropfen. Denn diese Übersetzung funktioniert nur auf Ihrem Rechner. Auf einem anderen Rechner wird das Verzeichnis und somit auch die Datei für die Übersetzung nicht gefunden. So haben Sie wieder nur englisch. Die Datei wird nicht automatisch gelinkt.

Beispiel 2

Um diesen Effekt zu verhindern sollten wir die Dateien dem Endverbraucher sprich User mitgeben. Also Erstellen wir ein Unterverzeichnis in unserem Programmpfad. Ich habe es hier mal „Sprachen“ genannt.

Wir legen ein Unterverzeichnis an.
Mein Programm verzeichnis heißt „dialog deutsch“

Jetzt müssen wir allerdings unseren Quelltext anpassen. Was dann wie folgt aussieht.

procedure TForm1.Button1Click(Sender: TObject);
var
  SchalterWahl: integer;
  SprachenPfad: string;
begin
  //Unterverzeichnis Sprachen
  SprachenPfad := ExtractFilePath(Application.ExeName) + '\Sprachen\';
  //Schalter nach deutsch
  TranslateUnitResourceStrings('LCLStrConsts',
    SprachenPfad + 'lclstrconsts.de.po');
  SchalterWahl := MessageDlg('Jetzt haben wir Schalter auf deutsch. ' +
    'Wollen Sie Schalter auf russisch?', mtConfirmation, mbYesNo, 0);
  // Bei nein beenden von klick
  if SchalterWahl = mrNo then Exit;
  //Schalter nach russisch
  TranslateUnitResourceStrings('LCLStrConsts',
    SprachenPfad + 'lclstrconsts.ru.po');
  SchalterWahl := MessageDlg('Wie gewünscht,Schalter auf russisch.',
    mtInformation, mbYesNo, 0);
end;

Wir definieren also eine Variable vom Typ string und nennen diese „SprachenPfad“. Hier wandeln wir die relative Position zu unserem Programm in einen absulten . Der Ort des Programms muss mit :

ExtractFilePath(Application.ExeName)

erfasst werden. Hinterher addieren wir unser Unterverzeichnis. Wenn wir nun das Programm als Zip-Format packen, können wir die Dateien bequem weitergeben. Beim Auspacken ist der relative Pfad immer gleich. Funktioniert sogar auf einem USB-Stick. Es dürfen aber niemals die Dateien entfernt oder das Unterverzeichnis umbenannt werden.

procedure TForm1.Button1Click(Sender: TObject);
begin
  //Schalter nach deutsch
  TranslateUnitResourceStrings('LCLStrConsts',
    'C:\lazarus\lcl\languages\lclstrconsts.de.po');
   //Provoziere Fehlermeldung
  chDir('Z:\Bilder von Omma\');
end;

Für alle die, die jetzt die Nase rümpfen.Pah… einzelne Dateien… das ist so amateurhaft. Denen kann man sagen, dass professionelle Programme, auch nicht nur aus einer Datei bestehen. Manchmal ergibt das Vorgehen auch einen Sinn. So auch hier. Es kommt auf die Anwendung an. Um die Skeptiker ruhig zu stellen, kommt hier nun Beispiel 3. Dies ist ziemlich lang, aber es verdeutlicht den Vorteil einer separaten po – Datei.

Beispiel 3

Vorbereitung: Erstellen sie eine IDE Anwendung und ziehen Sie eine TComboBox und einen TButton auf die Form. Kopieren Sie den Quelltext.

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  translations, FileUtil, StrUtils;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;
  SprachenPfad: string;
  SprachenDateiName: string;

implementation

{$R *.lfm}

{ TForm1 }

procedure BestueckeComboMitPO;
var
  F: integer;
  Temp: string;
begin
  with Form1.ComboBox1 do
  begin
    Items := FindAllFiles(SprachenPfad, '*.po', False);
    for F := 0 to Items.Count - 1 do
    begin
      Temp := Items[F];
      Delete(Temp, 1, Length(Temp) - 5);
      Temp := Copy2Symb(Temp, '.');
      Items[F] := Temp;
    end;
    Text:=Items[0];
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //Schalter nach deutsch
  TranslateUnitResourceStrings('LCLStrConsts',
    SprachenPfad + SprachenDateiName);
  MessageDlg('Jetzt haben wir Schalter auf ' + ComboBox1.Text, mtConfirmation, mbYesNo, 0);
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  SprachenDateiName := 'lclstrconsts.' + ComboBox1.Text + '.po';
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  //Unterverzeichnis Sprachen
  SprachenPfad := ExtractFilePath(Application.ExeName) + '\Sprachen\';
  BestueckeComboMitPO;
end;

end.

Nach dem Sie den Quelltext kopiert haben, müssen Sie noch die drei Ereignisse in dem Ojektexplorer anpassen.
ComboBox1 → OnChange
Button1 → OnClick
Form1 → OnActivate
Wenn Sie alles richtig gemacht haben, dann ergibt sich nach dem Start folgendes Bild, beim Aufklappen der Combobox. Natürlich nur unter der Voraussetzung, dass auch ein Unterverzeichnis Sprachen existiert.

Auswahl Dialoge mit deutschsprachigen und russischen Schaltern
deutsch und russisch

Nun können Sie noch weitere „lclstrconsts.xx.po“ aus dem „lazarus\lcl\Languages“ – Verzeichnis kopieren und das Programm passt sich an, ohne es neu kompilieren zu müssen. 🙂 Erkennen Sie nundas Potential ? Sie können mit der Technik nicht nur die Dialoge verändern sondern die Sprache von Ihrem Programm. Besser gesagt: Andere, die der Sprache mächtig sind, können das machen. Dazu brauchen diese Personen keine Kenntnisse über das Programmieren mit Lazarus. Nicht jeder Programmierer kann gleichzeitig auch viele Sprachen. Aber zunächst einmal….

Erläuterungen zum Quelltext

Wie üblich stellen wir erst einmal bei Form1OnActivate den absoluten Pfad fest. Dann Bestücken wir mit der Procedure BestueckeComboMitPO; die Combobox1. Das machen wir in dem Wir in dem Unterverzeichnis Sprachen nach den Dateien mit der Endung „po“ schauen. Hierfür bietet sich „FindAllFiles“ aus der Unit „FileUtil“ an. Danach schneiden wir die Sprachenbezeichnung aus dem Dateinamen aus. Zum Schluß wählen wir noch den ersten Eintrag für die Combobox1 als Text aus. Jetzt brauchen wir nur noch den „SprachenDateiName“ im OnChange – Ereignis zusammen zukleben und können so die Datei nach der Betätigung Laden.
Nun werden nur die Schalter und die Überschriften in Deutsche übersetzt. Viele Fehlermeldungen nicht. Die bleiben in Englisch. Die Dialoge wie Open- oder Fontdialoge sind von dem Umschalten auch nicht betroffen, diese bleiben auf deutsch, da diese Dialoge offensichtlich vom Betriebssystem gesteuert werden. Wenn sie wissen wollen was in den Dateien steht, dann laden Sie sich am besten „PoEdit“ herunter. Nach der Installation erkennen Sie die Funktion.