Inhaltsverzeichnis
Translate

GnuGetText tools for Delphi


Integration into Delphi programs

Defining the texts

All strings that are to be translated into other languages must be marked in the source text so that they can be clearly found by dxgettext when scanning the files.

Forms

Texts that are defined in a form, such as Caption, Hint and Text, are automatically recognized by dxgettext. The TranslateComponent function (see below) must be specified in the OnCreate event of the form in the source code of the associated unit.

Resource strings

All texts defined in a resourcestring section are automatically recognized and replaced by the respective translation during runtime.
Example:

   resourcestring
     msg = 'Hello, World'; 
     ... 

Other source text strings

Strings to be translated must be specified as an argument of one of the following functions so that they are recognized by dxgettext:
_(<string>), gettext(<string>) and dgettext(<domain><string>).

The functions are defined in the unit GnuGetText.
Examples:

   gettext('Hello, World');           // text definition for domain "default"
   _('Hello, World');                 // short form of function "gettext"
   dgettext('domain','Hello, World'); // same as "gettext" but for another domain
   ... 

Necessary program additions

Initializing the project

Some additions are required in the project's dpr file if other than the standard domain default are used and if certain components or classes, such as TFont, are to be excluded from the translation.
Example:

  program sample;
  
  uses
    GnuGetText in 'GnuGetText.pas',   // contains the functions called below
    Vcl.Forms,
    SampleMain in 'SampleMain.pas' {frmMerge};
  
  begin
    TP_GlobalIgnoreClass(TFont);      // exclude classes from translation 
    AddDomains(['delphi10','units']); // define additional text domains
  
    Application.Initialize;
    Application.MainFormOnTaskbar := True;
    Application.CreateForm(TfrmMain, frmMain);
    Application.Run;
  end.

First, the GnuGetText unit must be specified in the uses clause, as the functions to be called are defined in it. If required, one of the following functions can then be inserted before the application is initialized:

Descriptions of other possible functions can be found in the detailed description.

Integrate GnuGetText into units

In units that use a form, the texts used in the form must be replaced with the respective translations when the form is created. To do this, the TranslateComponent procedure must be called in the OnCreate event of the form.

Examples:

  procedure TMyForm.FormCreate (Sender: TObject);
    begin
    TranslateComponent (self);
    ...
    end;  
    
  procedure TMyForm.FormCreate (Sender: TObject);
    begin
    TranslateComponent (self,'units');
    ...
    end;  
    

Defining the language when starting the program

If the GnuGetText unit is included in the uses clause of the project file as described above, the user's display language of the system is automatically determined during its initialization (program section initialization) and saved as the default language. If the user wishes to use a different language, this can be done in the dpr file before application initialization by calling the Uselanguage procedure.
Example:

  program sample;
  
  uses
    GnuGetText in 'GnuGetText.pas',
    ...  
  begin
    AddDomains(['delphi10','units']);
    UseLanguage('de');
    ...  
  end.

Changing the language during runtime

First, the new language must be registered in the GnuGetText system. Then the TranslateComponent procedure must be called for each form used.
Example:

  procedure ChangeLanguage (NewLangCode : LanguageString);
  var
    i : integer;
  begin
    UseLanguage(NewLangCode);
    with Application do for i:=0 to ComponentCount-1 do if (Components[i] is TForm) then
      ReTranslateComponent(Components[i]);
    end;

The translations can either be integrated as mo files separately from the program's exe file or directly into the exe file.

Integrating as mo files

This procedure is to be preferred if several exe files in a project group use the same translations. When creating the installation package for this, they must be inserted with the same subdirectory structure, as described below.

The directory structure is somewhat convoluted and is best explained by the following example. First of all, there is a subdirectory locale in the directory with the executable program (exe file). Below this there is a further subdirectory for each supported language, the name of which must correspond to the abbreviation according to ISO639 (e.g. de, es, it). In each of these language-specific subdirectories there is then a further subdirectory LC_MESSAGES, which finally contains the mo files (default.mo and possibly those for other text domains) with the respective translations.
The following example will clarify the structure:

  <Exe directory>\  
    > locale\
      > de\ 
        > LC_MESSAGES\
          > default.mo         
          > delphi10.mo
      > es\ 
        > LC_MESSAGES\
          > default.mo         
          > delphi10.mo
      ...    

Embedding into the exe file

This procedure is suitable if only a single exe file is to be distributed. It then automatically contains all needed translations. It is not necessary to include the mo files and their somewhat complicated subdirectory.

The mo files of all languages to be used must first be copied into the subdirectories described above and then embed into the exe file using the ggassemble program.



J. Rathlev, D-24222 Schwentinental, November 2023