i18n in einer eigenen Komponente

Rund um die LCL und andere Komponenten
Antworten
wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

i18n in einer eigenen Komponente

Beitrag von wennerer »

Hallo zusammen,
ich möchte einer meiner eigenen Komponenten mittels i18n ein mehrsprachiges Popup Menü verpassen. Leider bekomme ich es nicht hin. Zum Testen habe ich mir eine Minimal- Komponente angelegt bei der durch anklicken ein Popup mit zwei Einträgen geöffnet wird.
In der Komponente habe ich i18n aktiviert.
i18n_1.png
i18n_1.png (25.45 KiB) 2595 mal betrachtet
Es wurde eine .po Datei erzeugt. Diese habe ich mit Poedit bearbeitet und eine .en.po abgespeichert. Wenn ich nun versuche mit setdefaultlang('en') diese Datei zu verwenden passiert leider nichts. Muss sich die Datei an einer bestimmten Stelle befinden? Bei Programmen musste ich sie in den gleichen Ordner wie die "exe" kopieren. Oder stimmt in meiner Herangehensweise sonst was nicht? Habe mittlerweile schon viel getestet und gelesen, komme aber leider nicht wirklich voran.

Hier der Code meiner Test-Komponente:

Code: Alles auswählen

unit TestKompo;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Menus, LCLTranslator;

type

  { TTestKompo }

  TTestKompo = class(TCustomControl)
  private
   FMenu              : TPopupMenu;
   FItem0             : TMenuItem;
   FItem1             : TMenuItem;
  protected
   procedure MouseDown(Button: TMouseButton;Shift: TShiftState; X, Y: Integer);override;
  public
   constructor Create(AOwner: TComponent); override;
   procedure Paint; override;
  published

  end;

 resourcestring
    TransText0  = 'Auswahl 1';
    TransText1  = 'Auswahl 2';


procedure Register;

implementation

procedure Register;
begin
  {$I testkompo_icon.lrs}
  RegisterComponents('Standard',[TTestKompo]);
end;

{ TTestKompo }

procedure TTestKompo.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);
  FMenu.PopUp;
end;

constructor TTestKompo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  setdefaultlang('en');

  FMenu:=TPopupMenu.Create(Self);
  FMenu.Parent := self;
  FMenu.SetSubComponent(true);

 //Auswahl 1
  FItem0:=TMenuItem.Create(Self);
  FItem0.Caption := TransText0;
  FMenu.Items.Add(FItem0);

 //Auswahl 2
  FItem1:=TMenuItem.Create(Self);
  FItem1.Caption := TransText1;
  FMenu.Items.Add(FItem1);
end;

procedure TTestKompo.Paint;
begin
  inherited Paint;
  self.Canvas.Brush.Color:= clYellow;
  self.Canvas.FillRect(0,0,width,height);
  self.Canvas.TextOut(2,5,'Kompo PopUp');
end;

end.
Ich hänge noch meinen Test an. Leider muss man sich dafür dann aber die kleine Testkomponente installieren (wird im Standard angelegt).

Ich würde mich freuen wenn mir Jemand weiter helfen könnte.

Viele Grüße
Bernd
Dateianhänge
i18n_Test_.zip
(71.68 KiB) 78-mal heruntergeladen

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: i18n in einer eigenen Komponente

Beitrag von fliegermichl »

Funktioniert bei mir (Win 10 64 Bit, Laz 2.0.11 FPC 3.2.0) auf Anhieb problemlos.

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: i18n in einer eigenen Komponente

Beitrag von wennerer »

Hallo,
danke für das Testen.
Hast du auf die kleine gelbe Komponente gedrückt? Der Button Open Popup war ein Test um ein Popup im Programm zu testen. Im Programm geht bei mir auch alles.
i18n_2.png
i18n_2.png (10.24 KiB) 2587 mal betrachtet

Viele Grüße
Bernd

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: i18n in einer eigenen Komponente

Beitrag von wp_xyz »

Ohne es jetzt im Detail ausprobiert zu haben, denke ich, dass das wahrscheinlich genauso funktioniert wie bei den Strings der LCL, die du ins locale-Verzeichnis des Programms kopieren muss, um die übersetzten LCL-Texte verwenden zu können (https://wiki.lazarus.freepascal.org/Ste ... by_the_LCL).

Also: Kopiere die Übersetzungen deiner Komponente ins locale-Verzeichnis deiner Anwendung und nimm die Unit mit den entsprechenden Resource-Strings in die Uses-Liste auf.

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: i18n in einer eigenen Komponente

Beitrag von wennerer »

@ wp_xyz: Erstmal vielen Dank für deine Antwort. Ich habe da jetzt einiges herumprobiert. Irgendwie ging es dann. Leider hab ich keine Ahnung wie ich es gemacht habe. :wink:
Ich muss da nochmal in Ruhe drüber nach denken.

Viele Grüße
Bernd

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: i18n in einer eigenen Komponente

Beitrag von wennerer »

Falls jemand in Zukunft auf diesen Beitrag stößt möchte ich noch meine Lösung anfügen. Sollte irgendwer Fehler entdecken oder eine bessere Lösung kennen dann bitte verbessern.
Prinzipiell hat wp_xyz recht, die Lösung steht in dem Wiki-Artikel. Die Tücke steckt nur im Detail.

Zuerst zum besseren Verständnis meine Kurzfassung des Wiki-Artikels:
- im Verzeichnis der „exe“ ein neues Verzeichnis mit den Namen locale oder languages anlegen. Die Namen sind wichtig sonst wird der Ordner nicht gefunden! Ich habe mich für
locale entschieden.
- in Lazarus auf Projekt, Projekteinstellungen, i18n
- dann einen Haken machen bei „i18n einschalten“
- bei PO-Ausgabeverzeichnis den Pfad zu dem Ordner locale eingeben.
transl01.png
transl01.png (28.68 KiB) 2470 mal betrachtet
- mit Ok verlassen.
- Ein Projekt ähnlich wie mein beigefügtes Beispiel anlegen und bei uses „LCLTranslator“ hinzufügen.
- Projekt mit F9 starten und wieder beenden. Jetzt befindet sich im Ordner locale eine Datei mit dem Namen_des_Projektes.po. Bei mir also MyTest.po
! Löscht man die .po Datei muss man auch die exe löschen damit die .po ein weiteres Mal erzeugt wird!
- wer die Datei öffnet sieht nun die Captions der im Objektinspektor erzeugten Komponenten und auch die selber definierten Resourcestrings.
- nun habe ich mir mit der Anwendungsverwaltung (Linux Mint)das Programm Poedit installiert.
- Mit Poedit die Datei MyTest.po öffnen
- Den Button „Sprache festlegen“ drücken und Sprache auswählen
- Die Übersetzungen eingeben.
- Dann mit „Speichern unter“ die Datei mit dem Namen MyTest.en.po speichern
- zum Testen in der FormCreate „SetDefaultlang('en'); “ eingeben und mit F9 starten
- Jetzt sollte alles in Englisch sein.

Jetzt zur eigenen Komponente:

- Eine Eigene Komponente ähnlich meiner TestKompo installieren. Die Komponente ähnlich wie das obige Projekt für Übersetzung vorbereiten. Ebenfalls einen Ordner locale anlegen.
- Nun das Package öffen. Geht u.a. so: Package, Geladenes Package öffnen, Package markieren und öffnen (oder einfach mit rechtsklick auf das Symbol in der Palette)
- in diesem Dialog auf Einstellungen, i18n dann wie oben
transl02.png
transl02.png (46.13 KiB) 2470 mal betrachtet
- Die Resourcestrings müssen in eine eigene Unit geschrieben werden. Bei mir die ResourceStringsTestKompo.pas
- Das Projekt mit F9 starten und beenden. Nun befinden sich im Ordner locale der Komponente die .po Dateien der Komponente. Die ResourceStringsTestKompo.po öffnen übersetzen und als .en.po speichern.
- Diese en.po in den locale Ordner des Projektes kopieren

(EDIT: Bitte nicht so weiter machen sondern unten weiterlesen!)

- Dann auf Projekt, Projektinspektor, Hinzufügen, Dateien aus dem Dateisystem hinzufügen und zur ResourceStringsTestKompo.pas navigieren und hinzufügen.
transl03.png
transl03.png (17.37 KiB) 2470 mal betrachtet
- Projekt mit F9 starten und beenden. Die Resourcestrings der Komponente stehen nun nicht übersetzt in der MyTest.en,po.
- MyTest.en.po mit Poedit öffnen. Dann auf Katalog, Vorübersetzung, Vorübersetzung, ok
- Jetzt werden alle Übersetzungen automatisch eingefügt! Speichern und beenden.
Jetzt sollte es funktionieren!
Details und Ordnerstruktur kann im Beispiel Projekt nachgeschaut werden.

Viele Grüße
Bernd
Dateianhänge
Translation02.zip
(73.54 KiB) 58-mal heruntergeladen
Zuletzt geändert von wennerer am So 7. Mär 2021, 19:17, insgesamt 2-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: i18n in einer eigenen Komponente

Beitrag von af0815 »

+1
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: i18n in einer eigenen Komponente

Beitrag von wp_xyz »

Wenn du aber später einmal deine eigene Komponente in ein Package packst, um sie z.B. in der IDE installieren zu können, handelst du dir wahrscheinlich Kompilierungsprobleme ein, da du in deiner Anwendung eine Unit des Packages explizit mit aufnimmst. Auch meine ich, wenn ich das richtig verstehe, dass du die Strings der Komponente für das Projekt neu übersetzen musst - deine Übersetzer werden sich freuen...

Der richtige Weg wäre, das Package wie üblich in die Anforderungsliste des Projekts aufzunehmen. Dann kopierst du die po-Dateien aus dem locale-Verzeichnis des Package ins locale-Verzeichnis der Anwendung. In der Anwendung nimmst du die Sprachunit in die Uses-Zeile auf. Wenn nun die Sprache gewechselt wird, musst du mit TranslateUnitResourceStrings die übersetzten Strings des Package aktivieren (denn LCLTranslator weißt nichts, davon dass noch eine weitere Unit übersetzt werden muss).

Ich habe das eben mit einigen Strings aus dem TAChart Package durchgespielt und ans Projekt beigefügt. Die Captions der Radiobuttons und der String, den der Click-Me Button anzeigen lässt, stammen aus diesem externen Package.
Dateianhänge
translated_chart.zip
(14.74 KiB) 77-mal heruntergeladen

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: i18n in einer eigenen Komponente

Beitrag von wennerer »

Eine Kleinigkeit vorweg für alle die das Beispiel von wp_xyz in Linux testen möchten. Ich musste die Zeile "fn := Application.Location + 'locale/TAChartStrConsts.%s.po'; " in "fn := Application.Location + 'locale/tachartstrconsts.%s.po';" ändern (Groß/Klein im Pfad).

Hallo wp_xyz,
Herzlichen Dank für deine ausführliche Antwort. Ich habe dein Programm mit großen Interesse getestet. Wenn ich das richtig sehe verknüpfst du Captions aus deinem Projekt mit Resourcestrings aus einer Komponente. Ich möchte jedoch das die Captions in meiner Komponente je nach gewählter Sprache im Projekt übersetzt werden. Das macht es zwar wenn ich es so mache wie oben beschrieben, aber du hast vollkommen recht das ich eine Abhängigkeit erzeuge die unter Umständen Probleme machen kann.
Die Lösung hast du mir (so denke ich zumindest) aber dennoch geliefert. Wenn ich TranslateUnitResourceStrings in meiner Komponente verwende scheint alles wunderbar zu funktionieren. Ich werde das alles nochmal in Ruhe testen und dann meinen obigen Bericht anpassen.
Eine Frage hätte ich jedoch noch, wie funktioniert das mit dem .%s? So was habe ich noch nie gesehen und wüsste auch nicht wonach ich da im Internet suchen sollte.

Viele Grüße
Bernd

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: i18n in einer eigenen Komponente

Beitrag von wp_xyz »

Das %s gehört zum Themen-Komplex "Format-Funktion". Der Funktion Format() ist gerade bei Übersetzungen sehr wichtig, denn du kannst eine Format-Maske definieren, in der du z.B. die Symbole %s durch Strings, %d durch Integer, oder %.3f durch einen Float (auf drei Dezimalstellen formatiert) ersetzen lassen kannst. Die Parameter werden als Konstanten-Array direkt als zweiter Parameter im Format-Aufruf angegeben und werden den Symbolen der Reihe nach zugeordnet (es sei denn du gibst gleich hinter dem %-Zeichen den Array-Index an, z.B. '%2:s' für das dritte Array-Element, das ein String sein muss)

Angenommen, es soll mit Showmessage ein Rechenergebnis (Breite eines Rechtecks) ausgegeben werden. Die Format-Maske für den Meldungstext wäre dann z.B.

Code: Alles auswählen

resourcestring 
  rsRectResult = 'The width of the rectangle is %d pixels, its height %d pixels.'; 
Die (freie) deutsche Übersetzung wäre wie folgt, allerdings will dein Chef die Höhe zuerst genannt haben , daher Parameter verwenden
Das Rechteck ist %1:d Pixel hoch und %0:d Pixel breit.'
Das kannst du dann so als ShowMessage anzeigen lassen

Code: Alles auswählen

 ShowMessage(Format(rsRectResult, [w, h]));
Auf englisch käme dann der Text für (w = 200, h = 100)
The width of the rectangle is 200 pixels, its height 100 pixels.
und auf deutsch
Das Rechteck ist 100 Pixel hoch und 200 Pixel breit.
Das ganze - und mehr - findest du auch unter https://www.freepascal.org/docs-html/rt ... ormat.html oder https://wiki.freepascal.org/Format_function.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: i18n in einer eigenen Komponente

Beitrag von wp_xyz »

wennerer hat geschrieben:
Mi 3. Mär 2021, 21:24
Ich möchte jedoch das die Captions in meiner Komponente je nach gewählter Sprache im Projekt übersetzt werden.
Spätestens, wenn das eine Komponente in einem Package ist, widerspricht das dem Package-Konzept. Denn das sind fertige Bausteine, und es macht wenig Sinn, wenn die Texte für jedes Projekt, das dein Package verwendet, neu übersetzt werden müssen.

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: i18n in einer eigenen Komponente

Beitrag von wennerer »

Hallo,
nochmals vielen Dank für deine Antwort und deine Geduld!
Ich werde nun erst mal versuchen alles was du mir mitgegeben hast richtig zu verstehen.

Viele Grüße
Bernd

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: i18n in einer eigenen Komponente

Beitrag von wennerer »

Hallo zusammen,
ich bin jetzt erst mal einige Schritte zurück gegangen und habe folgendes versucht:
Ich lege ein neues Projekt an (project1). Dieses statte ich mit i18n aus (Buttons, Caption und Resourcstrings). Ich lege .po Dateien für englisch und französisch an. Bis hierhin geht alles wie es gehen soll.
Jetzt füge ich in einer Button.Click einen MessageDialog hinzu (also dieses mal keine eigene Komponente). Ich kopiere die lclstrconsts.xx.po Dateien in mein locale Verzeichnis. Im project1 im FormCreate schreibe ich:

FLang :='fr'; //bzw. 'en' oder 'de'
SetDefaultLang(FLang);
fn := Application.Location + 'locale/lclstrconsts.%s.po';
Translations.TranslateUnitResourceStrings('LCLStrConsts', Format(fn, [Flang]));


Ergebnis in Linux: bei 'fr' werden die DialogButtons übersetzt (habe auch it und ru getestet und das geht auch),
linux_fr_.png
linux_fr_.png (19.04 KiB) 2318 mal betrachtet
bei 'de' und 'en' sind die DialogButtons deutsch.
linux_en_.png
linux_en_.png (17.84 KiB) 2318 mal betrachtet


Ergebnis in Windows : bei 'fr' und auch bei 'en' werden die DialogButtons in die richtige Sprache übersetzt, bei 'de' bleibt alles deutsch.
windows_en_.png
windows_en_.png (18.1 KiB) 2318 mal betrachtet

Ob ich die LCLStrConsts bei uses im project1 einbinde oder nicht macht keinen Unterschied (zumindest sehe ich keinen). Ich habe zusätzlich mittels Projektinspektor die LCLBase aufgenommen . Hat leider auch nichts gebracht.
Leider bleibt in Linux die englische Übersetzung der Komponente immer in deutsch während unter Windows scheinbar alles funktioniert.
Kann mich jemand über die richtige Vorgehensweise aufklären?

Viele Grüße
Bernd

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  LCLTranslator, Translations;//,lclstrconsts;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FLang : string;
  public

  end;

var
  Form1: TForm1;

resourcestring
  rsTitel = 'Deutsche Ausgabe';
  rsText  = 'deutsch';
implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var fn: String;
begin
  FLang :='en';
  SetDefaultLang(FLang);

  fn := Application.Location + 'locale/lclstrconsts.%s.po';
  Translations.TranslateUnitResourceStrings('LCLStrConsts', Format(fn, [Flang]));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MessageDlg(rsTitel, rsText, mtInformation, [mbOk, mbCancel, MbYes], 0);

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  MessageDlg(rsTitel,rsText, mtConfirmation, [mbyes, mbno, mbcancel], 0);
end;

end.
Dateianhänge
Translation05.zip
(96.3 KiB) 61-mal heruntergeladen

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: i18n in einer eigenen Komponente

Beitrag von wp_xyz »

Ich denke, das liegt daran, dass MessageDlg aus dem WidgetSet, also dem Betriebssystem kommt, und offenbar kriegt Linux nichts davon mit, dass du die Sprache geändert hast und liefert immer die Messagebox in der Systemsprache. Wahrscheinlich gibt es irgendwo eine Einstellung, in der du Linux die Sprache der Anwendung mitteilen kannst, nur kenne ich mich dazu in Linux zuwenig aus. Such mal im englischen Forum, vielleicht hat das jemand schon mal gesehen.

Speziell mit dem MessageDlg kannst du das Problem umgehen, indem du dir ein eigenes MessageDlg schreibst, aufbauend auf der Funktion CreateMessageDialog - diese wird voll von der LCL kontrolliert:

Code: Alles auswählen

function MessageDlg(const aCaption, aMsg: string; DlgType: TMsgDlgType;
            Buttons: TMsgDlgButtons; const AHelpCtx: Integer): TModalResult; 
begin
  with CreateMessageDialog(aCaption, aMsg, DlgType, Buttons) do
  begin
    HelpContext := AHelpCtx;  
    Result := ShowModal;
    Free;
  end;
end;
Aber spätestens, wenn du einen File-Dialog brauchst, geht dasselbe wahrscheinlich wieder los. Der ist übrigens auch in Windows teilweise deutsch beschriftet.

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: i18n in einer eigenen Komponente

Beitrag von wennerer »

Hallo,
danke für die Antwort. Ich habe zum Testen mal mein OS komplett auf Englisch umgestellt. Dann sind auch die Buttons und ein OpenDialog komplett in Englisch. Ich denke mal wer ein deutschsprachiges OS benutzt und auf Englisch umstellt wird mit ein paar Deutschen Captions (die vom WidgetSet bereitgestellt werden) leben können.

wp_xyz schrieb:
Der richtige Weg wäre, das Package wie üblich in die Anforderungsliste des Projekts aufzunehmen. Dann kopierst du die po-Dateien aus dem locale-Verzeichnis des Package ins locale-Verzeichnis der Anwendung. In der Anwendung nimmst du die Sprachunit in die Uses-Zeile auf. Wenn nun die Sprache gewechselt wird, musst du mit TranslateUnitResourceStrings die übersetzten Strings des Package aktivieren (denn LCLTranslator weißt nichts, davon dass noch eine weitere Unit übersetzt werden muss).
Ich denke prinzipiell war meine Vorgehensweise vom vorigen Beitrag nun die Richtige. Nach dem ich anfänglich dachte es gäbe je Sprache nur eine .po Datei musste ich zu erst begreifen das man erstens eine .po Datei je Sprache für das Project1 benötigt. Und für jedes weitere verwendete Package die benötigten .po Dateien je Sprache. Das alles kopiert man in das locale Verzeichnis vom Projekt1. Wird die Sprache gewechselt ruft man TranslateUnitResourceStrings für alle benötigten Units auf.

Im angefügten Test sieht man wie ich es jetzt gemacht habe. Ich hoffe das ist nun die richtige Vorgehensweise!

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  LCLTranslator, ExtCtrls, TestKompo, Translations;//,lclstrconsts;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    RadioGroup1: TRadioGroup;
    TestKompo1: TTestKompo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure RadioGroup1Click(Sender: TObject);
  private
    FLang : string;
    fn    : String;
  public

  end;

var
  Form1: TForm1;

resourcestring
  rsTitel   = 'English Edition';
  rsText    = 'english';
  rsEnglish = 'English';
  rsGerman  = 'German';
  rsFrench  = 'French';
implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  FLang :='de';
  //FLang :='en';
  //FLang :='fr';
  SetDefaultLang(FLang);
  //Lädt die Resourcestrings der LCL
  fn := Application.Location + 'locale/lclstrconsts.%s.po';
  Translations.TranslateUnitResourceStrings('LCLStrConsts', Format(fn, [Flang]));
  //Lädt die Resourcestrings der TestKomponente.Will man die Sprache nur beim Start setzen reicht es hier.
  fn := Application.Location + 'locale/resourcestringstestkompo.%s.po';
  Translations.TranslateUnitResourceStrings('resourcestringstestkompo', Format(fn, [Flang]));
  //Aktualisiert die PopUp-Menüeinträge
  TestKompo1.UpdateLanguage;

  RadioGroup1.Items[0]:= rsEnglish;
  RadioGroup1.Items[1]:= rsGerman;
  RadioGroup1.Items[2]:= rsFrench;
end;

procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
 case Radiogroup1.itemindex of
  0: FLang :='en';
  1: FLang :='de';
  2: FLang :='fr';
  end;
 //Resourcestrings aktualisieren
 SetDefaultLang(FLang);
 RadioGroup1.Items[0]:= rsEnglish;
 RadioGroup1.Items[1]:= rsGerman;
 RadioGroup1.Items[2]:= rsFrench;
 //Komponente aktualisieren
 Translations.TranslateUnitResourceStrings('resourcestringstestkompo', Format(fn, [Flang]));
 TestKompo1.UpdateLanguage;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MessageDlg(rsTitel, rsText, mtInformation, [mbOk, mbCancel, MbYes], 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
var OpenDialog : TOpenDialog;
begin
  OpenDialog         := TOpenDialog.Create(self);
  opendialog.Execute;
end;

end.
Viele Grüße
Bernd
Dateianhänge
Translation07.zip
(96.15 KiB) 60-mal heruntergeladen

Antworten