Recent

Author Topic: Num+ instead of NumPlus  (Read 3367 times)

Denis Bisson

  • Newbie
  • Posts: 3
Num+ instead of NumPlus
« on: December 05, 2016, 01:39:13 pm »
Hi!

Right now if we set a keyboard shortcut with keys like Num+, Num-, Num*, etc..., when the associated menu item is displayed the text that is display for the shortcut will be "NumPlus", "NumMinus", "NumMul"... From I've seen, this text is coming from function "GetSpecialShortCutName" in "lclproc.pas".

Is there a way to change that to "Num+", "Num-", "Num*" ? I've changed it directly in "lclproc.pas" and recompile the application and I see it works but I can't request collaborators on a projects to change their Lazarus files...

A few persons better like "Num+", "Num-", "Num*", etc. than "NumPlus", "NumMinus", "NumMul", etc.

For example "Num*" will be recognized much better for a international user, he figure better the key, than "NumMul". Do you think author could change that? Or could have a kind of call back routine to change that text or is there already a way to do it?

Thanks.

Denis.
« Last Edit: December 05, 2016, 01:52:09 pm by Denis Bisson »

howardpc

  • Hero Member
  • *****
  • Posts: 3362
Re: Num+ instead of NumPlus
« Reply #1 on: December 05, 2016, 03:17:19 pm »
I think there might be backwards compatibility issues if the Lazarus sources were changed in the way you propose.

Why not just use your own GetSpecialSCName() function, adapted from the original in LCLProc to suit your needs?

Denis Bisson

  • Newbie
  • Posts: 3
Re: Num+ instead of NumPlus
« Reply #2 on: December 05, 2016, 03:33:26 pm »

I think there might be backwards compatibility issues if the Lazarus sources were changed in the way you propose.
Why not just use your own GetSpecialSCName() function, adapted from the original in LCLProc to suit your needs?

  Hi howardpc!

  Regarding the backward compatibility issue, I understand.

  Sorry if I look stupid but how could I made the component drawing the menu to call my own GetSpecialShortcutName function?

Note:  Regarding my own GetSpecialShortcutName it's already done and it is in fact how the situation came up and someone bring it to my attention. In our application in a page where we show the keyboard shortcuts of the application in a single table, we show "Num+", "Num-", etc. We did it three years before "GetSpecialShortCutName" was returning "NumMul" in Lazarus by the way (have the proof in control version  :) ), but we never heard back until recently where someone pointed us that in our table showing the shorcuts it was showing "Num*" and in the menu it was showing "NumMul"... Certainly we can change what we're showing in our table for "NumMul" and so on, but you know... Num+, Num*, etc. are better looking. So I am asking...

Alextp

  • Hero Member
  • *****
  • Posts: 945
    • UVviewsoft
Re: Num+ instead of NumPlus
« Reply #3 on: December 08, 2016, 01:37:33 am »
IMO you are right, I typed in my LCL patch "NumMul" just as a guess. Try to replace to "Num*" and test how TextToShortcut works with string "Num*".

Test also how "Ctrl+Alt+Num+" works with TextToShortcut.
if it works, then try making the patch to Bugtracker.

howardpc

  • Hero Member
  • *****
  • Posts: 3362
Re: Num+ instead of NumPlus
« Reply #4 on: December 08, 2016, 12:41:00 pm »
  Sorry if I look stupid but how could I made the component drawing the menu to call my own GetSpecialShortcutName function?

I don't know how you can do this, unless your platform supports ownerdrawn menus (which several do not).
The LCL uses the underlying widgetset to draw the menus, so customisation is difficult (though perhaps not impossible if you are good at hacking).
On Linux for instance, both gtk2 and qt show a NumMul shortcut as simply * (not Num* nor NumMul - in the IDE the Object Inspector shows the shortcut as NumMul using GetSpecialShortcutName).
« Last Edit: December 08, 2016, 12:42:32 pm by howardpc »

ASerge

  • Hero Member
  • *****
  • Posts: 1503
Re: Num+ instead of NumPlus
« Reply #5 on: December 10, 2016, 04:28:43 am »
Example of hacking:
Code: Pascal  [Select]
  1. function NewShortCutToText(ShortCut: TShortCut): string;
  2. var
  3.   ScanCode: UINT;
  4.   KeyName: array [0..255] of Char;
  5.   KeyNameLen: Integer;
  6. begin
  7.   Result := '';
  8.   ScanCode := MapVirtualKey(ShortCut, 0);
  9.   if ScanCode <> 0 then
  10.   begin
  11.     case ShortCut of
  12.       VK_PRIOR..VK_DOWN,
  13.       VK_INSERT, VK_DELETE,
  14.       VK_LWIN..VK_APPS:
  15.         ScanCode := ScanCode or $100;
  16.     end;
  17.     KeyName[0] := #0; // Emit warning: Local variable "KeyName" does not seem to be initialized
  18.     KeyNameLen := GetKeyNameText(ScanCode shl 16, KeyName, SizeOf(KeyName));
  19.     if KeyNameLen > 0 then
  20.     begin
  21.       SetString(Result, KeyName, KeyNameLen);
  22.       if (ShortCut and scShift) <> 0 then
  23.         Result := 'Shift+' + Result;
  24.       if (ShortCut and scCtrl) <> 0 then
  25.         Result := 'Ctrl+' + Result;
  26.       if (ShortCut and scAlt) <> 0 then
  27.         Result := 'Alt+' + Result;
  28.     end;
  29.   end;
  30. end;
  31.  
  32. function RedirectProc(OldProc, NewProc: Pointer): Boolean;
  33. var
  34.   Code: packed record
  35.     Jmp: Byte;
  36.     Offset: LongInt; // Valid for x64 too
  37.   end;
  38.   NotUsed: PtrUInt;
  39. begin
  40.   Code.Jmp := $E9;
  41.   Code.Offset := PAnsiChar(NewProc) - PAnsiChar(OldProc) - SizeOf(Code);
  42.   NotUsed := 0; // Emit hint: Local variable "NotUsed" does not seem to be initialized
  43.   Result := WriteProcessMemory(GetCurrentProcess, OldProc, @Code, SizeOf(Code), NotUsed);
  44. end;

and test:
Code: Pascal  [Select]
  1. procedure TForm1.FormActivate(Sender: TObject);
  2. var
  3.   ShortCut: TShortCut;
  4.   L: TStringList;
  5. begin
  6.   L := TStringList.Create;
  7.   try
  8.     for ShortCut := $8 to $80 do
  9.       L.Append(Format('%.2x'#9'%s'#9'%s',
  10.         [ShortCut, ShortCutToText(ShortCut), NewShortCutToText(ShortCut)]));
  11.     L.Append(StringOfChar('-', 40));
  12.     Memo1.Text := L.Text;
  13.     if RedirectProc(@ShortCutToText, @NewShortCutToText) then
  14.     begin
  15.       for ShortCut := $8 to $80 do
  16.         L.Append(Format('%.2x'#9'%s'#9'%s',
  17.           [ShortCut, ShortCutToText(ShortCut), NewShortCutToText(ShortCut)]));
  18.       Memo1.Text := L.Text;
  19.     end;
  20.   finally
  21.     L.Free;
  22.   end;
  23. end;

howardpc

  • Hero Member
  • *****
  • Posts: 3362
Re: Num+ instead of NumPlus
« Reply #6 on: December 10, 2016, 11:31:34 am »
@ASerge: Is MapVirtualKey() an OS-specific call?
If not, where do we find it?

ASerge

  • Hero Member
  • *****
  • Posts: 1503
Re: Num+ instead of NumPlus
« Reply #7 on: December 10, 2016, 03:08:39 pm »
@ASerge: Is MapVirtualKey() an OS-specific call?
Sorry, it Windows only (MapVirtualKey, GetKeyNameText, WriteProcessMemory, GetCurrentProcess) and x86 architecture (jmp near instruction).