Jump to content
Sign in to follow this  
UCT_24

Localization of VCL Dialogs

Recommended Posts

Hello,
i am having trouble "localizing" VCL built-in dialogs.

Generally, i think there is multi-language support for the VCL.
Also, there are means of localizing custom forms and vcl controls at runtime.

But i could not find documentation or examples on how i can have for example the buttons in a "Vcl.Forms.TApplication.MessageBox" displayed with english or german captions?

The Captions vary when using the System settings, switching "Windows language", but i would like to switch language "at runtime" of the application, so, if you like.
To be more precise:
For example i call the MessageBox function and have it displaying one "OK" and one "CANCEL" button.
I would like to make sure in application code that the Button Captions are displayed in english or german (independent of the windows language settings).

The same applies for the VCL "Dialogs::MessageDlg" buttons. Buttons are added by "System::Uitypes::TMsgDlgBtn"-type idenifiers, but the resulting buttons on the form can not be localized in the described way.

This should also apply for "shortcut" caption extensions.
For example i add a menu with a TShortCut that is using a key identifier (extern DELPHI_PACKAGE System::Classes::TShortCut __fastcall ShortCut(System::Word Key, System::Classes::TShiftState Shift);).
These ShortCuts are displayed on the UI as a "caption extension". But i do not know how to have them displayed according to language chosen at runtime.

Is this maybe impossible to switch display language of such controls at runtime?
And if possible, does anyone know how to achieve this? 

 

Thanks in advance and kind regards,
Ulrich

Share this post


Link to post

Button captions and such are defined by resourcestrings. For example, see Vcl.Consts.pas:

resourcestring
  [...lots of strings...]
  SOKButton = 'OK';
  SCancelButton = 'Cancel';
  SYesButton = '&Yes';
  SNoButton = '&No';
  SHelpButton = '&Help';
  SCloseButton = '&Close';
  SIgnoreButton = '&Ignore';
  SRetryButton = '&Retry';
  SAbortButton = 'Abort';
  SAllButton = '&All';

You can use any of of the many different localization solutions to have them translated. E.g. this one: https://bitbucket.org/anders_melander/better-translation-manager

Share this post


Link to post

Many thanks for your reply, i will check this file.

I have read about resource strings before, and i was sure that there are Resource Strings defined for all the standard dialogs.
But how to switch between languages at runtime then (assumed i already have resource strings translated)?
At the moment, as far as i can see, the VCL will consider the resource strings matching the windows language.

Is there a specific function call to "force" a specific language/resource string mapping?
 

Kind regards,

ulrich

 

Share this post


Link to post

I use simply this, limited to common standard system strings, of course this is a skeleton ...

 

form the Main program you can use it in this way:

TTraduzione.ChangeValues('IT');

 

unit uTraduzione;

interface
uses
  WinApi.Windows, System.SysUtils, Vcl.Consts;

Type
  TTraduzione = Class
 public
    class procedure SetResourceString(const xOldResourceString: PResStringRec; const xValueChanged: PChar);
  public
     class procedure ChangeValues(Lingua: string = '');
  End;

implementation

class procedure TTraduzione.SetResourceString(const xOldResourceString: PResStringRec; const xValueChanged: PChar);
var
  POldProtect: DWORD;
  PLostProtect: DWORD;
begin
  VirtualProtect(xOldResourceString, SizeOf(xOldResourceString^),
                 PAGE_READWRITE, @POldProtect);
  xOldResourceString^.Identifier := NativeUInt(xValueChanged);
  VirtualProtect(xOldResourceString, SizeOf(xOldResourceString^), POldProtect,
                 @PLostProtect);
end;

class procedure TTraduzione.ChangeValues(Lingua: string = '');
begin
   if Lingua = 'IT' then
        begin
          //Carica la lingua italiana
          SetResourceString(@SMsgDlgYes, '&Si');
          SetResourceString(@SMsgDlgWarning,'Attenzione');
          SetResourceString(@SMsgDlgError, 'Errore');
          SetResourceString(@SMsgDlgInformation, 'Informazione');
          SetResourceString(@SMsgDlgConfirm , 'Conferma');
          SetResourceString(@SMsgDlgNo , '&No');
          SetResourceString(@SMsgDlgOK , 'OK');
          SetResourceString(@SMsgDlgCancel , 'Annulla');
          SetResourceString(@SMsgDlgHelp , '&Aiuto');
          SetResourceString(@SMsgDlgHelpHelp , 'Aiuto');
          SetResourceString(@SMsgDlgHelpNone , 'Nessun aiuto disponibile');
          SetResourceString(@SMsgDlgAbort , '&Termina');
          SetResourceString(@SMsgDlgRetry , '&Riprova');
          SetResourceString(@SMsgDlgIgnore , '&Ignora');
          SetResourceString(@SMsgDlgAll , '&Tutto');
          SetResourceString(@SMsgDlgNoToAll , 'N&o a Tutto');
          SetResourceString(@SMsgDlgYesToAll , 'Si a &Tutto');
          SetResourceString(@SMsgDlgClose , '&Chiudi');
        end
      else
        if Lingua = 'EN' then
          begin
            //Carica la lingua inglese
            SetResourceString(@SMsgDlgYes, '&Yes');
            SetResourceString(@SMsgDlgWarning,'Warning');
            SetResourceString(@SMsgDlgError, 'Error');
            SetResourceString(@SMsgDlgInformation, 'Information');
            SetResourceString(@SMsgDlgConfirm , 'Confirm');
            SetResourceString(@SMsgDlgNo , '&No');
            SetResourceString(@SMsgDlgOK , 'OK');
            SetResourceString(@SMsgDlgCancel , 'Cancel');
            SetResourceString(@SMsgDlgHelp , '&Help');
            SetResourceString(@SMsgDlgHelpHelp , 'Help');
            SetResourceString(@SMsgDlgHelpNone , 'No Help Available');
            SetResourceString(@SMsgDlgAbort , '&Abort');
            SetResourceString(@SMsgDlgRetry , '&Retry');
            SetResourceString(@SMsgDlgIgnore , '&Ignore');
            SetResourceString(@SMsgDlgAll , '&All');
            SetResourceString(@SMsgDlgNoToAll , 'N&o to All');
            SetResourceString(@SMsgDlgYesToAll , 'Yes to &All');
            SetResourceString(@SMsgDlgClose , '&Close');
          end
        else
          if Lingua = 'ES' then
            begin
              //Carica la lingua spagnola
              SetResourceString(@SMsgDlgYes, '&Si');
              SetResourceString(@SMsgDlgWarning,'Advertencia');
              SetResourceString(@SMsgDlgError, 'Error');
              SetResourceString(@SMsgDlgInformation, 'Información');
              SetResourceString(@SMsgDlgConfirm , 'Confirmar');
              SetResourceString(@SMsgDlgNo , '&No');
              SetResourceString(@SMsgDlgOK , 'OK');
              SetResourceString(@SMsgDlgCancel , 'Cancelar');
              SetResourceString(@SMsgDlgHelp , '&Ayuda');
              SetResourceString(@SMsgDlgHelpHelp , 'Ayuda');
              SetResourceString(@SMsgDlgHelpNone , 'No hay ayuda disponible');
              SetResourceString(@SMsgDlgAbort , '&Termina');
              SetResourceString(@SMsgDlgRetry , 'Intentar &otra vez');
              SetResourceString(@SMsgDlgIgnore , '&Ignorar');
              SetResourceString(@SMsgDlgAll , '&Todos');
              SetResourceString(@SMsgDlgNoToAll , 'N&o a todo');
              SetResourceString(@SMsgDlgYesToAll , 'S&i a todo');
              SetResourceString(@SMsgDlgClose , '&Cerrar');
            end
          else
            begin
			....................
		    ....................
		    ....................
            end;
end;

 

  • Like 1

Share this post


Link to post
Posted (edited)
18 minutes ago, UCT_24 said:

At the moment, as far as i can see, the VCL will consider the resource strings matching the windows language.

 

You can add a registry entry under HKEY_CURRENT_USER\SOFTWARE\Embarcadero\Locales for that. Of course that only works at application start, so no change at runtime possible.

 

One tool supporting changing languages at runtime is Korzh Localizer.

Edited by Uwe Raabe

Share this post


Link to post

Thanks for your answers,
i'll try that registry key. Switching language at program start might be enough if the language can be read from a configuration file.
But, do i get this right, i have to add code to manipulate this registry key right at the entry point of the application?
Or will it be necessarry to switch the registry key BEFORE the program is run, because VCL component initialization has already been done when i enter the main routine of the program?
Thanks a lot so far and kind regards,
Ulrich

Share this post


Link to post

Another option could be calling SetLocaleOverride with the desired value. It just has to be done quite early as long as no resources are being loaded.

Share this post


Link to post

Ok, so i think my best Option will be to try both and see what works better.
I will keep you updated 🙂
Thanks again and kind regards,
Ulrich

Share this post


Link to post

Hello again,
i tried to put a registry key in HKEY_CURRENT_USER\SOFTWARE\Embarcadero\Locales and took the existing keys as example.
But using my .exe path as key and "en-GB" as Value (REG_SZ entry) does only affect some, but not all VCL dialogs. The "Vcl.Forms.TApplication.MessageBox" and the "FileChooser (not sure about the exact class name here)" are not affected by the registry key, but the "messageDlg" from the VCl and the Menu-Shortcut Captions are displayed as desired.


I tried switching the language set for bds.exe, and this changes the display language of the bds.exe.

Maybe i need to perform the steps to apply languages when compiling the application first?
 

However, " SetLocaleOverride" Function does not seem to have an effect.

Share this post


Link to post
15 minutes ago, UCT_24 said:

The "Vcl.Forms.TApplication.MessageBox" and the "FileChooser (not sure about the exact class name here)" are not affected by the registry key

These dialogs are not part of your application, but are provided by the operating system and thus follow the Windows settings. There is not much you can do about it.

 

17 minutes ago, UCT_24 said:

I tried switching the language set for bds.exe, and this changes the display language of the bds.exe.

The app BDSSetLang.exe found in teh Delphi bin folder has an option to change the Library language apart from the IDE language. This will use another set of resources when compiling your application.

Share this post


Link to post

Hello,

to your first reply, i was afraid so. However, it totally makes sense, unfortunately.
Regarding the BDSSetLang, i will try this when i have the opportunity.

Thanks a lot for your kind assistance, it helped me a lot.

Kind regards,

Ulrich

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×