the Solution is simple:
copy the Source Code of my last Posting into
globals.pasCreate a Program file:
{$mode delphi}
program test;
uses
globals, Dialogs;
begin
ShowMessage(tr('done.'));
end.
Dialogs is need for ShowMessage
The used *.mo files, you need
msgfmt.exe Tool - on my Side it comes with MingW64 / MSYS2.
To compile the .po file to .mo file: simply on Console:
msgfmt -o executable_path/locale/de.mo de.po
Here is the skeleton/stub/header of the structure of a .po file:
# Sharp signs are one line comments
# the first msgid and msgstr must be empty - I think it is for self references the mo file itselfmsgid = ""
msgstr = ""
"Project-Id-Version: 1.13.2\n"
"POT-Creation-Date: 2025-02-21 20:33+0100\n"
"PO-Revision-Date: 2025-02-21 20:15+0100\n"
"Last-Translator: Jens Kallup <paule32@gmail.com>\n"
"Language-Team: German <paule32@gmail.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
# now, you can define the String-ID msgid and the translation for it as msgstr
# this will translate ShowMessage(tr('Hello World')); to ShowMessage('The life is short');
msgid = "Hello World"
msgstr = "The life is short"
The rest is trival (on Console):
Here is a make-up Version of globals.pas:
{$mode delphi}
unit globals;
interface
uses
SysUtils, LCLIntf, LCLType, LCLProc, Translations, GetText, Dialogs;
type
TMoTranslate = class(TMoFile)
private
FLangID: String;
public
constructor Create(ALang: String; ACheck: Boolean = false); overload;
destructor Destroy; override;
function getLangID: String;
end;
function tr(AString: String): String;
implementation
uses
{$IFDEF WINDOWS}
Windows;
{$ENDIF}
var
motr: TMoTranslate;
function tr(AString: String): String;
begin
if motr = nil then
motr := TMoTranslate.Create('de', false);
result := motr.Translate(AString);
end;
constructor TMoTranslate.Create(ALang: String; ACheck: Boolean);
[code=pascal]{$IFDEF WINDOWS}
const LOCALE_NAME_MAX_LENGTH = 2;
var
LangID: LCID;
Buffer: array[0..LOCALE_NAME_MAX_LENGTH] of Char;
{$ENDIF}
var
filePath: String;
begin
{$IFDEF WINDOWS}
if ACheck then
begin
// Windows: GetThreadLocale gibt die Locale ID zurück
case GetThreadLocale of
$0001: FLangID := 'ar';
$0002: FLangID := 'bg';
$0003: FLangID := 'ca';
$0004: FLangID := 'zh';
$0005: FLangID := 'cs';
$0006: FLangID := 'da';
$0007: FLangID := 'de';
$0008: FLangID := 'el';
$0009: FLangID := 'en';
$000A: FLangID := 'es';
else begin
FLangID := 'en';
end;
end;
if GetLocaleInfo(LangID, LOCALE_SISO639LANGNAME, Buffer, SizeOf(Buffer)) > 0 then
begin
FLangID := Buffer;
end;
end else
begin
FLangID := ALang;
end;
{$ELSE}
if ACheck then
begin
FLangID := GetEnvironmentVariable('LANG');
if FLangID = '' then
FLangID := 'en' else
FLangID := Copy(FLangID, 1, 2);
end else
begin
FLangID := ALang;
end;
{$ENDIF}
filePath := ExtractFilePath(ParamStr(0)) + 'locale/' + FLangID + '.mo';
if FileExists(filePath) then
begin
inherited Create(filePath);
end else
begin
raise Exception.Create('translator file not found: ' + filePath);
end;
end;
destructor TMoTranslate.Destroy;
begin
inherited Destroy;
end;
function TMoTranslate.getLangID: String;
begin
result := FLangID;
end;
end.
And yes, I realize that the Documentation is a little bit buggy - because they provide *.po information.
And if you use plain/raw .po files the RTL of Lazarus/FPC will raise a Exception.