SiComponents Home Page SiComponents Forums
Here you will be able to get help and share your experience
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Translation of Shortcuts in Menus

 
Post new topic   Reply to topic    SiComponents Forums Forum Index -> TsiLang Components Suite
View previous topic :: View next topic  
Author Message
kai



Joined: 06 Aug 2003
Posts: 2

PostPosted: Wed Aug 06, 2003 4:43 pm    Post subject: Translation of Shortcuts in Menus Reply with quote

Hi,

I am using the TSILang and I am very satisfied with them. I have only on problem: I can't translate the Shortcut names of Menuitems. That means, that "Strg+N" is replaced with "Ctrl+N". Is there a solution for this?

Kai
Back to top
View user's profile Send private message
isiticov
Site Admin


Joined: 21 Nov 2002
Posts: 2094

PostPosted: Thu Aug 07, 2003 8:26 am    Post subject: Reply with quote

Unfortunately, Borland didn't make these strings (shortcut names) used as resource strings when translating shortcut values to string representation in menus unit.
So this is possible only by altering code in standard Menus.Pas unit and translating resource strings responsible for shortcut names using resource string wizard from expert. If this is acceptable for you we can provide step by step instructions. Let us know about your decision.
Back to top
View user's profile Send private message
stem



Joined: 07 Aug 2003
Posts: 3

PostPosted: Thu Aug 07, 2003 11:03 am    Post subject: Reply with quote

Hi,

I have the same question as kai.

I've developed internationalization functions
for BCB 4 on my own which work perfectly,
even for Japanese. The language file are
simple text files which are loaded at
run-time.

The *only* thing left to translate are the
menu shortcuts.

If anybody as any ideas, let me know! Very Happy


Thanx, Stefan
Back to top
View user's profile Send private message
isiticov
Site Admin


Joined: 21 Nov 2002
Posts: 2094

PostPosted: Thu Aug 07, 2003 1:30 pm    Post subject: Reply with quote

In SiComp.pas unit there is procedure called:
procedure OverwriteProcedure(OldProcedure, NewProcedure: Pointer);

Just copy it into your code and use the following example code which allows translation menu shortcuts:
Code:

function SiShortCutToText(ShortCut: TShortCut): string;

implementation
{$R *.dfm}

function GetSpecialName(ShortCut: TShortCut): string;
var
  ScanCode: Integer;
  KeyName: array[0..255] of Char;
begin
  Result := '';
  ScanCode := MapVirtualKey(WordRec(ShortCut).Lo, 0) shl 16;
  if ScanCode <> 0 then
  begin
    GetKeyNameText(ScanCode, KeyName, SizeOf(KeyName));
    GetSpecialName := KeyName;
  end;
end;

function SiShortCutToText(ShortCut: TShortCut): string;
var
  Name: string;
begin
  case WordRec(ShortCut).Lo of
    $08: Name := Form1.siLang1.GetTextOrDefault('IDS_0' (* 'BkSp' *) );
    $09: Name := Form1.siLang1.GetTextOrDefault('IDS_1' (* 'Tab' *) );
    $0D: Name := Form1.siLang1.GetTextOrDefault('IDS_2' (* 'Enter' *) );
    $1B: Name := Form1.siLang1.GetTextOrDefault('IDS_3' (* 'Esc' *) );
    $20: Name := Form1.siLang1.GetTextOrDefault('IDS_4' (* 'Space' *) );
    $21: Name := Form1.siLang1.GetTextOrDefault('IDS_5' (* 'PgUp' *) );
    $22: Name := Form1.siLang1.GetTextOrDefault('IDS_6' (* 'PgDn' *) );
    $23: Name := Form1.siLang1.GetTextOrDefault('IDS_7' (* 'End' *) );
    $24: Name := Form1.siLang1.GetTextOrDefault('IDS_8' (* 'Home' *) );
    $25: Name := Form1.siLang1.GetTextOrDefault('IDS_9' (* 'Left' *) );
    $26: Name := Form1.siLang1.GetTextOrDefault('IDS_10' (* 'Up' *) );
    $27: Name := Form1.siLang1.GetTextOrDefault('IDS_11' (* 'Right' *) );
    $28: Name := Form1.siLang1.GetTextOrDefault('IDS_12' (* 'Down' *) );
    $2D: Name := Form1.siLang1.GetTextOrDefault('IDS_13' (* 'Ins' *) );
    $2E: Name := Form1.siLang1.GetTextOrDefault('IDS_14' (* 'Del' *) );
    $30..$39: Name := Chr(WordRec(ShortCut).Lo - $30 + Ord('0'));
    $41..$5A: Name := Chr(WordRec(ShortCut).Lo - $41 + Ord('A'));
    $60..$69: Name := Chr(WordRec(ShortCut).Lo - $60 + Ord('0'));
    $70..$87: Name := 'F' + IntToStr(WordRec(ShortCut).Lo - $6F);
  else
    Name := GetSpecialName(ShortCut);
  end;
  if Name <> '' then
  begin
    Result := '';
    if ShortCut and scShift <> 0 then Result := Result + Form1.siLang1.GetTextOrDefault('IDS_15' (* 'Shift+' *) );
    if ShortCut and scCtrl <> 0 then Result := Result + Form1.siLang1.GetTextOrDefault('IDS_16' (* 'Ctrl+' *) );
    if ShortCut and scAlt <> 0 then Result := Result + Form1.siLang1.GetTextOrDefault('IDS_17' (* 'Alt+' *) );
    Result := Result + Name;
  end
  else Result := '';
end;

type
    TAccessMenu = class(TMenu);

procedure TForm1.Language1Click(Sender: TObject);
begin
  siLang1.ActiveLanguage := TComponent(Sender).Tag;
  TAccessMenu(MainMenu1).UpdateItems;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TAccessMenu(MainMenu1).UpdateItems;
end;

initialization
  OverwriteProcedure(@ShortCutToText, @SiShortCutToText);
end.



Hope this helps.
Back to top
View user's profile Send private message
stem



Joined: 07 Aug 2003
Posts: 3

PostPosted: Wed Aug 13, 2003 10:44 am    Post subject: Reply with quote

Hi,

I've read your answer but still can't see how the
translation of menu shortcuts in general works
(especially without TsiLang components).

It would be great if you can describe the steps
I need to do a little bit more in detail.


Thanx alot and greetings from *hot* Germany

Stefan
Back to top
View user's profile Send private message
isiticov
Site Admin


Joined: 21 Nov 2002
Posts: 2094

PostPosted: Wed Aug 13, 2003 11:04 am    Post subject: Reply with quote

The answer was how to translate the shortcuts using TsiLang Components Suite.
In order to translate them without using TsiLang Components Suite I can suggest the following way:
1. Delphi/C++Builder show shortcuts in menu after converting the shortcut value (word) to text prezentation.
2. This is done using ShortCutToText() function from Menus.pas unit.
3. Unfortunately, Borland didn't make the strings that are used in this conversation used as resource strings. You can see this by investigating original source code of ShortCutToText() function from Menus.pas unit.
4. So in order to translate this you can make a "hack" by overwriting the ShortcutToText() function in your executable by yours implementation. And in your implementation just use strings corresponding to shortcut modifiers as Shift, CTRL... and using your translate algorithm translate them.

OverwriteProcedure is implemented like this:

Code:
procedure OverwriteProcedure(OldProcedure, NewProcedure: pointer);
var
  x: pchar;
  y: integer;
  ov2, ov: cardinal;
begin
  x := PChar(OldProcedure);
  if not VirtualProtect(Pointer(x), 5, PAGE_EXECUTE_READWRITE, @ov) then
    RaiseLastOSError;

  x[0] := char($E9);
  y := integer(NewProcedure) - integer(OldProcedure) - 5;
  x[1] := char(y and 255);
  x[2] := char((y shr 8) and 255);
  x[3] := char((y shr 16) and 255);
  x[4] := char((y shr 24) and 255);

  if not VirtualProtect(Pointer(x), 5, ov, @ov2) then
    RaiseLastOSError;
end;
Back to top
View user's profile Send private message
stem



Joined: 07 Aug 2003
Posts: 3

PostPosted: Wed Aug 13, 2003 4:10 pm    Post subject: Reply with quote

Hi!

Thanx for your answer!

I've converted your code into C++. Does anybody find any
errors? At least it compiles without errors or warnings ... Very Happy

Code:

void OverwriteProcedure(Pointer OldProcedure, Pointer NewProcedure)
{
   PChar x;
   int y;
   unsigned long ov2, ov;

   x = PChar(OldProcedure);

   if (!VirtualProtect(Pointer(x), 5, PAGE_EXECUTE_READWRITE, &ov))
      RaiseLastWin32Error();

   x[0] = char('E9');

   y = int(NewProcedure) - int(OldProcedure) - 5;

   x[1] = char(y & 255);
   x[2] = char((y >> 8) & 255);
   x[3] = char((y >> 16) & 255);
   x[4] = char((y >> 24) & 255);

   if (!VirtualProtect(Pointer(x), 5, ov, &ov2))
      RaiseLastWin32Error();
}


Unfortunately, Borland C++ Builder 4 doesn't have a file
called "Menus.pas". It only has some headers or already
compiled files.

Could anyone, please, post the ShortcutToText() function
here?

By the way: Where should I call the overwrite function?
Before any forms are created?

Thanx

Stefan
Back to top
View user's profile Send private message
isiticov
Site Admin


Joined: 21 Nov 2002
Posts: 2094

PostPosted: Wed Aug 20, 2003 7:33 am    Post subject: Reply with quote

Below is example code from C++ Builder to perform discussed task:

Code:

AnsiString __fastcall SiShortCutToText(TShortCut ShortCut)
{
  AnsiString res = "AAA";
  return (res);
}

void OverwriteProcedure(Pointer OldProcedure, Pointer NewProcedure)
{
   PChar x;
   int y;
   unsigned long ov2, ov;

   x = PChar(OldProcedure);

   if (!VirtualProtect(Pointer(x), 5, PAGE_EXECUTE_READWRITE, &ov))
      RaiseLastWin32Error();

   x[0] = 0xE9;

   y = int(NewProcedure) - int(OldProcedure) - 5;

   x[1] = char(y & 255);
   x[2] = char((y >> 8) & 255);
   x[3] = char((y >> 16) & 255);
   x[4] = char((y >> 24) & 255);

   if (!VirtualProtect(Pointer(x), 5, ov, &ov2))
      RaiseLastWin32Error();
}


void __fastcall TForm1::FormCreate(TObject *Sender)
{
  OverwriteProcedure(&ShortCutToText, &SiShortCutToText);
  // to update menu and recreate shortcuts
  MainMenu1->Images = NULL;
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    SiComponents Forums Forum Index -> TsiLang Components Suite All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by p h p B B  © 2001, 2005 p h p B B  Group