Jump to content
Dirk Janssens

Using translations in unit Consts with Delphi 10.4 VCL

Recommended Posts

Hello,

 

I try to translate the captions of the buttons in the MessageDlg in Delphi 10.4, VCL.

 

If I add the unit consts.pas to my project, wich contains 1 line of code :" Messagedlg('Hoi', mtconfirmation, [mbYes.mbNo],0) " , the the captions of the unit are used. (Ja,Nee)

In a big project ( > 100 units) I also add the unit to the project ( in the project directory) , but the Dialogs ignore the translations. It seems lile they keep using the vcl.consts unit,
What do I have to do, to force my project to only use the translated Consts,pas in the project-folder.

 

I tried editing the unit C:\Program Files (x86)\Embarcadero\Studio\21.0\source\vcl\VCL.Consts.pas but i get errors when I save it (unable to crate backup), and I prefer not to edit the original Delphi Units.
 

Any suggestions are very welcome...

kind regards,

Dirk Janssens.

Share this post


Link to post

I once found it on the internet. It never disappointed me.

unit slovensky;

interface

implementation
uses
  System.Classes,
  Vcl.Forms, Vcl.Consts, Vcl.Dialogs;

resourcestring
  SMsgDlgCZWarning = 'Výstraha';
  SMsgDlgCZError = 'Chyba';
  SMsgDlgCZInformation = 'Informácia';
  SMsgDlgCZConfirm = 'Potvrdiť'; // Otázka
  SMsgDlgCZYes = 'Án&o';
  SMsgDlgCZNo = '&Nie';
  SMsgDlgCZOK = 'OK';
  SMsgDlgCZCancel = 'Zruš';
  SMsgDlgCZHelp = 'Nápoveď';
//  SMsgDlgCZHelpNone = 'Nápoveď nie je';
//  SMsgDlgCZHelpHelp = 'Nápoveď';
  SMsgDlgCZAbort = '&Zrušiť';
  SMsgDlgCZRetry = 'Opakovať';
  SMsgDlgCZIgnore = '&Ignorovať';
  SMsgDlgCZAll = '&Všetko';
  SMsgDlgCZNoToAll = 'Nie všetkým';
  SMsgDlgCZYesToAll = 'Ano všetkýmm';
  SMsgDlgCZClose = 'Zavrieť';

const
  Captions: array[TMsgDlgType] of Pointer = (@SMsgDlgCZWarning,
  @SMsgDlgCZError,
  @SMsgDlgCZInformation, @SMsgDlgCZConfirm, nil);

  ButtonCaptions: array[TMsgDlgBtn] of Pointer = (
    @SMsgDlgCZYes, @SMsgDlgCZNo, @SMsgDlgCZOK, @SMsgDlgCZCancel,
    @SMsgDlgCZAbort,
    @SMsgDlgCZRetry, @SMsgDlgCZIgnore, @SMsgDlgCZAll, @SMsgDlgCZNoToAll,
    @SMsgDlgCZYesToAll,
    @SMsgDlgCZHelp,
    @SMsgDlgCZClose);

{$WARN SYMBOL_PLATFORM OFF}

procedure _ChangeCaptions(List: TPointerList; Last: Pointer);
const
  Two = 2;
var
  I, Max: Integer;
  IsFind: Boolean;
begin
  {$R-}
  try
    Max  := (Integer(Last)-Integer(List)) div SizeOf(Pointer);
    IsFind  := False;

    for I := 0 to Max - Two do
      if (List[I] = @SMsgDlgWarning) and (List[I + Two] = @SMsgDlgInformation) then
      begin
        IsFind  := True;
        break;
      end;

    if IsFind then
      Move(Captions, List[I], SizeOf(Captions));

    IsFind  := False;

    for I := I to Max - Two do
      if (List[I] = @SMsgDlgYes) and (List[I + Two] = @SMsgDlgOK) then
      begin
        IsFind  := True;
        break;
      end;

    if IsFind then
      Move(ButtonCaptions, List[I], SizeOf(ButtonCaptions));
  finally
    {$R+}
  end;
end;

initialization
//  _ChangeCaptions(@DebugHook, @Application);

end.

 

Share this post


Link to post

Thank you very much, but I do not understand how to use this.
If I add it to my projrect, the messageDialogs automatically use this unit for the captions ?  

 

kind regards,

Dirk

Share this post


Link to post

I have copied Vcl.Consts.pas and System.SysConst.pas to my project folder. I have added them to my project and in them, made translations.

With each new version of Delphi, I use WinMerge to find differences and solve them, otherwise it does not compile anymore.

Share this post


Link to post

That is how it works for my simpel project, but for the more complex one I see not why it does not work.
Can it be that the cause is that I name the unit "Consts.pas", and not "VCL.consts.pas" ? 

 

Share this post


Link to post
2 minutes ago, Dirk Janssens said:

That is how it works for my simpel project, but for the more complex one I see not why it does not work.
Can it be that the cause is that I name the unit "Consts.pas", and not "VCL.consts.pas" ? 

 

Definitely. It will also not work if you build your project with runtime packages.

Share this post


Link to post
3 hours ago, Dirk Janssens said:

It seems lile they keep using the vcl.consts unit

This will only work if you have the sources for every components you are using and you also build them all at least once at building the release version aaaand your units will be found earlier than the dcu's in Delphi's lib directory.

 

So it wasn't for me, I'm using this:

 

const
  MY_SMsgDlgConfirm = 'Moooooooo';

implementation

procedure HookResourceString(rs: PResStringRec; newStr: PChar);
var
  oldprotect: DWORD;
begin
  VirtualProtect(rs, SizeOf(rs^), PAGE_EXECUTE_READWRITE, @oldprotect);
  rs^.Identifier := Integer(newStr);
  VirtualProtect(rs, SizeOf(rs^), oldprotect, @oldprotect);
end;

initialization

HookResourceString(@SMsgDlgConfirm, MY_SMsgDlgConfirm);

 

No one ever complained about it.

 

 

Was it originaly from you @PeterBelow?  http://www.delphigroups.info/2/92/298063.html

 

 

 

Edited by Attila Kovacs

Share this post


Link to post

 

16 hours ago, Stano said:

I once found it on the internet. It never disappointed me.

 

I tried it ,but nothing happens. I suppose I have to execute the initialization-part? 
But the line 
_ChangeCaptions(@DebugHook, @Application); 
raises error
[dcc32 Error] slovensky.pas(84): E2010 Incompatible types: 'TPointerList' and 'Pointer'

Can you tell me how and where I need to call the _ChangeCaptions 

Share this post


Link to post

I have the Slovensky.pas file quoted only in * .dpr. I'm not setting anything anywhere. I use TSM. I'm bypassing the OS dialogs. I can't say more about that.

Share this post


Link to post
18 hours ago, Attila Kovacs said:

This will only work if you have the sources for every components you are using and you also build them all at least once at building the release version aaaand your units will be found earlier than the dcu's in Delphi's lib directory.

 

So it wasn't for me, I'm using this:

...

 

 

Was it originaly from you @PeterBelow?  http://www.delphigroups.info/2/92/298063.html

 

Yes. That was ages ago, makes me realize how old I've gotten now...

 

 

  • Like 1

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

×