View Issue Details

IDProjectCategoryView StatusLast Update
0030992PatchesLCLpublic2018-07-28 21:56
ReporterCudaText manAssigned ToMichl 
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionfixed 
Product Version1.6.3 (SVN)Product Build 
Target VersionFixed in Version 
Summary0030992: ShortcutToText faster, with array
DescriptionThis makes 1) fast ShortcutToText, using array[1..255] of string. part of this array elements get value from Laz consts
(about 20 items). so result must be the same.
I 've read all key names at MS site.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
 
2) KeyAndShiftStateToKeyString also redone
(to use this array and not crappy function)
TagsNo tags attached.
Fixed in Revision57373
LazTarget-
Widgetset
Attached Files
  • key2.diff (16,350 bytes)
    Index: lcl/lclproc.pas
    ===================================================================
    --- lcl/lclproc.pas	(revision 53427)
    +++ lcl/lclproc.pas	(working copy)
    @@ -467,10 +467,275 @@
       MenuKeyCaps: array[TMenuKeyCap] of string;
       MenuKeyCapsInited: boolean = false;
     
    +const
    +  // MS documentation:
    +  // https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
    +  //
    +  KeyCodeStrings: array[1..$FF] of string = (
    +    'Mouse_Left', // 0x1 - VK_LBUTTON
    +    'Mouse_Right', // 0x2 - VK_RBUTTON
    +    'Cancel', // 0x3 - VK_CANCEL - generated by Ctrl+Break
    +    'Mouse_Middle', // 0x4 - VK_MBUTTON
    +    'Mouse_X1', // 0x5 - VK_XBUTTON1
    +    'Mouse_X2', // 0x6 - VK_XBUTTON2
    +    '', // 0x7
    +    'Backspace', // 0x8 - VK_BACK
    +    'Tab', // 0x9 - VK_TAB
    +    '', // 0xa
    +    '', // 0xb
    +    'NumClear', // 0xc - VK_CLEAR - generated by Num5 (NumLock off)
    +    'Enter', // 0xd - VK_RETURN
    +    '', // 0xe
    +    '', // 0xf
    +    'Shift', // 0x10 - VK_SHIFT
    +    'Ctrl', // 0x11 - VK_CONTROL
    +    'Alt', // 0x12 - VK_MENU
    +    'Break', // 0x13 - VK_PAUSE - Pause/Break key
    +    'CapsLock', // 0x14 - VK_CAPITAL
    +    'IME_Kana', // 0x15 - VK_KANA
    +    '', // 0x16
    +    'IME_Junja', // 0x17 - VK_JUNJA
    +    'IME_final', // 0x18 - VK_FINAL
    +    'IME_Hanja', // 0x19 - VK_HANJA
    +    '', // 0x1a
    +    'Esc', // 0x1b - VK_ESCAPE
    +    'IME_convert', // 0x1c - VK_CONVERT
    +    'IME_nonconvert', // 0x1d - VK_NONCONVERT
    +    'IME_accept', // 0x1e - VK_ACCEPT
    +    'IME_mode_change', // 0x1f - VK_MODECHANGE
    +    'Space', // 0x20 - VK_SPACE
    +    'PgUp', // 0x21 - VK_PRIOR
    +    'PgDown', // 0x22 - VK_NEXT
    +    'End', // 0x23 - VK_END
    +    'Home', // 0x24 - VK_HOME
    +    'Left', // 0x25 - VK_LEFT
    +    'Up', // 0x26 - VK_UP
    +    'Right', // 0x27 - VK_RIGHT
    +    'Down', // 0x28 - VK_DOWN
    +    'Select', // 0x29 - VK_SELECT
    +    'Print', // 0x2a - VK_PRINT
    +    'Execute', // 0x2b - VK_EXECUTE
    +    'PrintScreen', // 0x2c - VK_SNAPSHOT
    +    'Ins', // 0x2d - VK_INSERT
    +    'Del', // 0x2e - VK_DELETE
    +    'Help', // 0x2f - VK_HELP
    +    '0', // 0x30
    +    '1', // 0x31
    +    '2', // 0x32
    +    '3', // 0x33
    +    '4', // 0x34
    +    '5', // 0x35
    +    '6', // 0x36
    +    '7', // 0x37
    +    '8', // 0x38
    +    '9', // 0x39
    +    '', // 0x3a
    +    '', // 0x3b
    +    '', // 0x3c
    +    '', // 0x3d
    +    '', // 0x3e
    +    '', // 0x3f
    +    '', // 0x40
    +    'A', // 0x41
    +    'B', // 0x42
    +    'C', // 0x43
    +    'D', // 0x44
    +    'E', // 0x45
    +    'F', // 0x46
    +    'G', // 0x47
    +    'H', // 0x48
    +    'I', // 0x49
    +    'J', // 0x4a
    +    'K', // 0x4b
    +    'L', // 0x4c
    +    'M', // 0x4d
    +    'N', // 0x4e
    +    'O', // 0x4f
    +    'P', // 0x50
    +    'Q', // 0x51
    +    'R', // 0x52
    +    'S', // 0x53
    +    'T', // 0x54
    +    'U', // 0x55
    +    'V', // 0x56
    +    'W', // 0x57
    +    'X', // 0x58
    +    'Y', // 0x59
    +    'Z', // 0x5a
    +    'LWindows', // 0x5b - VK_LWIN
    +    'RWindows', // 0x5c - VK_RWIN
    +    'PopUp', // 0x5d - VK_APPS - PC, key near right Ctrl
    +    '', // 0x5e
    +    'Sleep', // 0x5f - VK_SLEEP
    +    'Num0', // 0x60 - VK_NUMPAD0
    +    'Num1', // 0x61
    +    'Num2', // 0x62
    +    'Num3', // 0x63
    +    'Num4', // 0x64
    +    'Num5', // 0x65
    +    'Num6', // 0x66
    +    'Num7', // 0x67
    +    'Num8', // 0x68
    +    'Num9', // 0x69 - VK_NUMPAD9
    +    'NumMul', // 0x6a - VK_MULTIPLY
    +    'NumPlus', // 0x6b - VK_ADD
    +    'NumSepar', // 0x6c - VK_SEPARATOR
    +    'NumMinus', // 0x6d - VK_SUBTRACT
    +    'NumDot', // 0x6e - VK_DECIMAL
    +    'NumDiv', // 0x6f - VK_DIVIDE
    +    'F1', // 0x70 - VK_F1
    +    'F2', // 0x71
    +    'F3', // 0x72
    +    'F4', // 0x73
    +    'F5', // 0x74
    +    'F6', // 0x75
    +    'F7', // 0x76
    +    'F8', // 0x77
    +    'F9', // 0x78
    +    'F10', // 0x79
    +    'F11', // 0x7a
    +    'F12', // 0x7b
    +    'F13', // 0x7c
    +    'F14', // 0x7d
    +    'F15', // 0x7e
    +    'F16', // 0x7f
    +    'F17', // 0x80
    +    'F18', // 0x81
    +    'F19', // 0x82
    +    'F20', // 0x83
    +    'F21', // 0x84
    +    'F22', // 0x85
    +    'F23', // 0x86
    +    'F24', // 0x87 - VK_F24
    +    '', // 0x88
    +    '', // 0x89
    +    '', // 0x8a
    +    '', // 0x8b
    +    '', // 0x8c
    +    '', // 0x8d
    +    '', // 0x8e
    +    '', // 0x8f
    +    'NumLock', // 0x90 - VK_NUMLOCK
    +    'ScrollLock', // 0x91 - VK_SCROLL
    +    'OEM_0x92', // 0x92
    +    'OEM_0x93', // 0x93
    +    'OEM_0x94', // 0x94
    +    'OEM_0x95', // 0x95
    +    'OEM_0x96', // 0x96
    +    '', // 0x97
    +    '', // 0x98
    +    '', // 0x99
    +    '', // 0x9a
    +    '', // 0x9b
    +    '', // 0x9c
    +    '', // 0x9d
    +    '', // 0x9e
    +    '', // 0x9f
    +    'LShift', // 0xa0 - VK_LSHIFT
    +    'RShift', // 0xa1 - VK_RSHIFT
    +    'LCtrl', // 0xa2 - VK_LCONTROL
    +    'RCtrl', // 0xa3 - VK_RCONTROL
    +    'LAlt', // 0xa4 - VK_LMENU
    +    'RAlt', // 0xa5 - VK_RMENU
    +    'BrowserBack', // 0xa6 - VK_BROWSER_BACK
    +    'BrowserForward', // 0xa7 - VK_BROWSER_FORWARD
    +    'BrowserRefresh', // 0xa8 - VK_BROWSER_REFRESH
    +    'BrowserStop', // 0xa9 - VK_BROWSER_STOP
    +    'BrowserSearch', // 0xaa - VK_BROWSER_SEARCH
    +    'BrowserFav', // 0xab - VK_BROWSER_FAVORITES
    +    'BrowserHome', // 0xac - VK_BROWSER_HOME
    +    'VolumeMute', // 0xad - VK_VOLUME_MUTE
    +    'VolumeDown', // 0xae - VK_VOLUME_DOWN
    +    'VolumeUp', // 0xaf - VK_VOLUME_UP
    +    'MediaNext', // 0xb0 - VK_MEDIA_NEXT_TRACK
    +    'MediaPrev', // 0xb1 - VK_MEDIA_PREV_TRACK
    +    'MediaStop', // 0xb2 - VK_MEDIA_STOP
    +    'MediaPlayPause', // 0xb3 - VK_MEDIA_PLAY_PAUSE
    +    'LaunchMail', // 0xb4 - VK_LAUNCH_MAIL
    +    'LaunchMedia', // 0xb5 - VK_LAUNCH_MEDIA_SELECT
    +    'LaunchApp1', // 0xb6 - VK_LAUNCH_APP1
    +    'LaunchApp2', // 0xb7 - VK_LAUNCH_APP2
    +    '', // 0xb8
    +    '', // 0xb9
    +    ';', // 0xba - VK_OEM_1 - Can vary by keyboard, US keyboard, the ';:' key
    +    '+', // 0xbb - VK_OEM_PLUS - For any country/region, the '+' key
    +    ',', // 0xbc - VK_OEM_COMMA - For any country/region, the ',' key
    +    '-', // 0xbd - VK_OEM_MINUS - For any country/region, the '-' key
    +    '.', // 0xbe - VK_OEM_PERIOD - For any country/region, the '.' key
    +    '/', // 0xbf - VK_OEM_2 - Can vary by keyboard, US keyboard, the '/?' key
    +    '`', // 0xc0 - VK_OEM_3 - Can vary by keyboard, US keyboard, the '`~' key
    +    '', // 0xc1
    +    '', // 0xc2
    +    '', // 0xc3
    +    '', // 0xc4
    +    '', // 0xc5
    +    '', // 0xc6
    +    '', // 0xc7
    +    '', // 0xc8
    +    '', // 0xc9
    +    '', // 0xca
    +    '', // 0xcb
    +    '', // 0xcc
    +    '', // 0xcd
    +    '', // 0xce
    +    '', // 0xcf
    +    '', // 0xd0
    +    '', // 0xd1
    +    '', // 0xd2
    +    '', // 0xd3
    +    '', // 0xd4
    +    '', // 0xd5
    +    '', // 0xd6
    +    '', // 0xd7
    +    '', // 0xd8
    +    '', // 0xd9
    +    '', // 0xda
    +    '[', // 0xdb - VK_OEM_4 - Can vary by keyboard, US keyboard, the '[{' key
    +    '\', // 0xdc - VK_OEM_5 - Can vary by keyboard, US keyboard, the '\|' key
    +    ']', // 0xdd - VK_OEM_6 - Can vary by keyboard, US keyboard, the ']}' key
    +    '''', // 0xde - VK_OEM_7 - Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
    +    'OEM_8', // 0xdf - VK_OEM_8
    +    '', // 0xe0
    +    'OEM_0xE1', // 0xe1
    +    '\', // 0xe2 - VK_OEM_102 - Either the angle bracket key or the backslash key on the RT 102-key keyboard
    +    'OEM_0xE3', // 0xe3
    +    'OEM_0xE4', // 0xe4
    +    'IME_process', // 0xe5 - VK_PROCESSKEY
    +    'OEM_0xE6', // 0xe6
    +    'UnicodePacket', // 0xe7 - VK_PACKET
    +    '', // 0xe8
    +    'OEM_0xE9', // 0xe9
    +    'OEM_0xEA', // 0xea
    +    'OEM_0xEB', // 0xeb
    +    'OEM_0xEC', // 0xec
    +    'OEM_0xED', // 0xed
    +    'OEM_0xEE', // 0xee
    +    'OEM_0xEF', // 0xef
    +    'OEM_0xF0', // 0xf0
    +    'OEM_0xF1', // 0xf1
    +    'OEM_0xF2', // 0xf2
    +    'OEM_0xF3', // 0xf3
    +    'OEM_0xF4', // 0xf4
    +    'OEM_0xF5', // 0xf5
    +    'Attn', // 0xf6 - VK_ATTN
    +    'CrSel', // 0xf7 - VK_CRSEL
    +    'ExSel', // 0xf8 - VK_EXSEL
    +    'EraseEOF', // 0xf9 - VK_EREOF
    +    'Play', // 0xfa - VK_PLAY
    +    'Zoom', // 0xfb - VK_ZOOM
    +    '', // 0xfc
    +    'PA1', // 0xfd - VK_PA1
    +    'OEM_Clear', // 0xfe - VK_OEM_CLEAR
    +    '' // 0xff
    +  );
    +
    +
     procedure InitializeMenuKeyCaps;
     begin
    -  if MenuKeyCapsInited=false then
    +  if not MenuKeyCapsInited then
       begin
    +    MenuKeyCapsInited:=true;
    +
         MenuKeyCaps[mkcBkSp]:=SmkcBkSp;
         MenuKeyCaps[mkcTab]:=SmkcTab;
         MenuKeyCaps[mkcEsc]:=SmkcEsc;
    @@ -490,58 +755,25 @@
         MenuKeyCaps[mkcCtrl]:=SmkcCtrl;
         MenuKeyCaps[mkcAlt]:=SmkcAlt;
         MenuKeyCaps[mkcMeta]:=SmkcMeta;
    -    MenuKeyCapsInited:=true;
    -  end;
    -end;
     
    -function GetSpecialShortCutName(Key: integer): string;
    -begin
    -  Result := '';
    -  case Key of
    -    VK_CANCEL:     Result := 'Cancel'; //generated by Ctrl+Break
    -    VK_CLEAR:      Result := 'NumClear'; //generated by Num5 (NumLock off)
    -    VK_PAUSE:      Result := 'Break';
    -    VK_CAPITAL:    Result := 'CapsLock';
    -    VK_APPS:       Result := 'PopUp'; //PC, near right Ctrl
    -    VK_MULTIPLY:   Result := 'NumMul';
    -    VK_ADD:        Result := 'NumPlus';
    -    VK_SUBTRACT:   Result := 'NumMinus';
    -    VK_DECIMAL:    Result := 'NumDot';
    -    VK_DIVIDE:     Result := 'NumDiv';
    -    VK_NUMLOCK:    Result := 'NumLock';
    -    VK_SCROLL:     Result := 'ScrollLock';
    -    VK_OEM_1:      Result := ';'; // Can vary by keyboard, US keyboard, the ';:' key
    -    VK_OEM_PLUS:   Result := '+'; // For any country/region, the '+' key
    -    VK_OEM_COMMA:  Result := ','; // For any country/region, the ',' key
    -    VK_OEM_MINUS:  Result := '-'; // For any country/region, the '-' key
    -    VK_OEM_PERIOD: Result := '.'; // For any country/region, the '.' key
    -    VK_OEM_2:      Result := '/'; // Can vary by keyboard, US keyboard, the '/?' key
    -    VK_OEM_3:      Result := '`'; // Can vary by keyboard, US keyboard, the '`~' key
    -    VK_OEM_4:      Result := '['; // Can vary by keyboard, US keyboard, the '[{' key
    -    VK_OEM_5:      Result := '\'; // Can vary by keyboard, US keyboard, the '\|' key
    -    VK_OEM_6:      Result := ']'; // Can vary by keyboard, US keyboard, the ']}' key
    -    VK_OEM_7:      Result := ''''; // Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
    -    VK_OEM_102:    Result := '\'; // Either the angle bracket key or the backslash key on the RT 102-key keyboard
    -
    -    //Windows keyboard special:
    -    $A6: Result := 'BrowserBack';
    -    $A7: Result := 'BrowserForward';
    -    $A8: Result := 'BrowserRefresh';
    -    $A9: Result := 'BrowserStop';
    -    $AA: Result := 'BrowserSearch';
    -    $AB: Result := 'BrowserFav';
    -    $AC: Result := 'BrowserHome';
    -    $AD: Result := 'VolumeMute';
    -    $AE: Result := 'VolumeDown';
    -    $AF: Result := 'VolumeUp';
    -    $B0: Result := 'MediaNext';
    -    $B1: Result := 'MediaPrev';
    -    $B2: Result := 'MediaStop';
    -    $B3: Result := 'MediaPlay';
    -    $B4: Result := 'LaunchMail';
    -    $B5: Result := 'LaunchMedia';
    -    $B6: Result := 'LaunchApp1';
    -    $B7: Result := 'LaunchApp2';
    +    KeyCodeStrings[VK_BACK]:=SmkcBkSp;
    +    KeyCodeStrings[VK_TAB]:=SmkcTab;
    +    KeyCodeStrings[VK_ESCAPE]:=SmkcEsc;
    +    KeyCodeStrings[VK_RETURN]:=SmkcEnter;
    +    KeyCodeStrings[VK_SPACE]:=SmkcSpace;
    +    KeyCodeStrings[VK_PRIOR]:=SmkcPgUp;
    +    KeyCodeStrings[VK_NEXT]:=SmkcPgDn;
    +    KeyCodeStrings[VK_END]:=SmkcEnd;
    +    KeyCodeStrings[VK_HOME]:=SmkcHome;
    +    KeyCodeStrings[VK_LEFT]:=SmkcLeft;
    +    KeyCodeStrings[VK_UP]:=SmkcUp;
    +    KeyCodeStrings[VK_RIGHT]:=SmkcRight;
    +    KeyCodeStrings[VK_DOWN]:=SmkcDown;
    +    KeyCodeStrings[VK_INSERT]:=SmkcIns;
    +    KeyCodeStrings[VK_DELETE]:=SmkcDel;
    +    KeyCodeStrings[VK_SHIFT]:=SmkcShift;
    +    KeyCodeStrings[VK_CONTROL]:=SmkcCtrl;
    +    KeyCodeStrings[VK_MENU]:=SmkcAlt;
       end;
     end;
     
    @@ -575,6 +807,14 @@
         Result:=DefaultValue;
     end;
     
    +function KeyCodeToKeyString(Key: integer): string;
    +begin
    +  if (Key>=Low(KeyCodeStrings)) and (Key<=High(KeyCodeStrings)) then
    +    Result := KeyCodeStrings[Key]
    +  else
    +    Result := '';
    +end;
    +
     // Used also by TWidgetSet.GetAcceleratorString
     function KeyAndShiftStateToKeyString(Key: word; ShiftState: TShiftState): String;
     
    @@ -585,79 +825,8 @@
         Result := Result + APart;
       end;
     
    -  // Tricky routine. This only works for western languages
    -  procedure AddKey;
    -  begin
    -    case Key of
    -      VK_UNKNOWN    :AddPart(ifsVK_UNKNOWN);
    -      VK_LBUTTON    :AddPart(ifsVK_LBUTTON);
    -      VK_RBUTTON    :AddPart(ifsVK_RBUTTON);
    -      VK_CANCEL     :AddPart(ifsVK_CANCEL);
    -      VK_MBUTTON    :AddPart(ifsVK_MBUTTON);
    -      VK_BACK       :AddPart(ifsVK_BACK);
    -      VK_TAB        :AddPart(ifsVK_TAB);
    -      VK_CLEAR      :AddPart(ifsVK_CLEAR);
    -      VK_RETURN     :AddPart(ifsVK_RETURN);
    -      VK_SHIFT      :AddPart(ifsVK_SHIFT);
    -      VK_CONTROL    :AddPart(ifsVK_CONTROL);
    -      VK_MENU       :AddPart(ifsVK_MENU);
    -      VK_PAUSE      :AddPart(ifsVK_PAUSE);
    -      VK_CAPITAL    :AddPart(ifsVK_CAPITAL);
    -      VK_KANA       :AddPart(ifsVK_KANA);
    -    //  VK_HANGUL     :AddPart('Hangul');
    -      VK_JUNJA      :AddPart(ifsVK_JUNJA);
    -      VK_FINAL      :AddPart(ifsVK_FINAL);
    -      VK_HANJA      :AddPart(ifsVK_HANJA );
    -    //  VK_KANJI      :AddPart('Kanji');
    -      VK_ESCAPE     :AddPart(ifsVK_ESCAPE);
    -      VK_CONVERT    :AddPart(ifsVK_CONVERT);
    -      VK_NONCONVERT :AddPart(ifsVK_NONCONVERT);
    -      VK_ACCEPT     :AddPart(ifsVK_ACCEPT);
    -      VK_MODECHANGE :AddPart(ifsVK_MODECHANGE);
    -      VK_SPACE      :AddPart(ifsVK_SPACE);
    -      VK_PRIOR      :AddPart(ifsVK_PRIOR);
    -      VK_NEXT       :AddPart(ifsVK_NEXT);
    -      VK_END        :AddPart(ifsVK_END);
    -      VK_HOME       :AddPart(ifsVK_HOME);
    -      VK_LEFT       :AddPart(ifsVK_LEFT);
    -      VK_UP         :AddPart(ifsVK_UP);
    -      VK_RIGHT      :AddPart(ifsVK_RIGHT);
    -      VK_DOWN       :AddPart(ifsVK_DOWN);
    -      VK_SELECT     :AddPart(ifsVK_SELECT);
    -      VK_PRINT      :AddPart(ifsVK_PRINT);
    -      VK_EXECUTE    :AddPart(ifsVK_EXECUTE);
    -      VK_SNAPSHOT   :AddPart(ifsVK_SNAPSHOT);
    -      VK_INSERT     :AddPart(ifsVK_INSERT);
    -      VK_DELETE     :AddPart(ifsVK_DELETE);
    -      VK_HELP       :AddPart(ifsVK_HELP);
    -      VK_0..VK_9    :AddPart(chr(ord('0')+Key-VK_0));
    -      VK_A..VK_Z    :AddPart(chr(ord('A')+Key-VK_A));
    -      VK_LWIN       :AddPart(ifsVK_LWIN);
    -      VK_RWIN       :AddPart(ifsVK_RWIN);
    -      VK_APPS       :AddPart(ifsVK_APPS);
    -      VK_NUMPAD0..VK_NUMPAD9:  AddPart(Format(ifsVK_NUMPAD,[Key-VK_NUMPAD0]));
    -      VK_MULTIPLY   :AddPart('*');
    -      VK_ADD        :AddPart('+');
    -      VK_OEM_PLUS   :AddPart('+');
    -      VK_SEPARATOR  :AddPart('|');
    -      VK_SUBTRACT   :AddPart('-');
    -      VK_OEM_MINUS  :AddPart('-');
    -      VK_DECIMAL    :AddPart('.');
    -      VK_OEM_PERIOD :AddPart('.');
    -      VK_OEM_COMMA  :AddPart(',');
    -      VK_DIVIDE     :AddPart('/');
    -      VK_F1..VK_F24: AddPart('F'+IntToStr(Key-VK_F1+1));
    -      VK_NUMLOCK    :AddPart(ifsVK_NUMLOCK);
    -      VK_SCROLL     :AddPart(ifsVK_SCROLL);
    -      VK_OEM_2      :AddPart('OEM2');
    -      VK_OEM_3      :AddPart('OEM3');
    -//    VK_EQUAL      :AddPart('=');
    -//    VK_AT         :AddPart('@');
    -    else
    -      AddPart(UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX);
    -    end;
    -  end;
    -
    +var
    +  S: string;
     begin
       Result := '';
       if ssCtrl in ShiftState then AddPart(ifsCtrl);
    @@ -670,7 +839,12 @@
         AddPart(ifsVK_META);
         {$ENDIF}
       if ssSuper in ShiftState then AddPart(ifsVK_SUPER);
    -  AddKey;
    +
    +  S := KeyCodeToKeyString(Key);
    +  // function returned "Word(nnn)" previously, keep this
    +  if S='' then
    +    S := UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX;
    +  AddPart(S);
     end;
     
     function KeyStringIsIrregular(const s: string): boolean;
    @@ -679,36 +853,6 @@
         (AnsiStrLComp(PChar(s),PChar(UNKNOWN_VK_PREFIX),length(UNKNOWN_VK_PREFIX))=0);
     end;
     
    -function KeyCodeToKeyString(Key: integer): string;
    -begin
    -  case Key of
    -    VK_BACK:
    -      Result := MenuKeyCaps[mkcBkSp];
    -    VK_TAB:
    -      Result := MenuKeyCaps[mkcTab];
    -    VK_RETURN:
    -      Result := MenuKeyCaps[mkcEnter];
    -    VK_ESCAPE:
    -      Result := MenuKeyCaps[mkcEsc];
    -    VK_SPACE..VK_SPACE+8:
    -      Result := MenuKeyCaps[TMenuKeyCap(Key - VK_SPACE + Ord(mkcSpace))];
    -    VK_INSERT:
    -      Result := MenuKeyCaps[mkcIns];
    -    VK_DELETE:
    -      Result := MenuKeyCaps[mkcDel];
    -    VK_0..VK_9:
    -      Result := Chr(Key - VK_0 + Ord('0'));
    -    VK_A..VK_Z:
    -      Result := Chr(Key - VK_A + Ord('A'));
    -    VK_NUMPAD0..VK_NUMPAD9:
    -      Result := 'Num' + Chr(Key - VK_NUMPAD0 + Ord('0')); // Delphi differs it from 0..9
    -    VK_F1..VK_F24:
    -      Result := 'F' + IntToStr(Key - (VK_F1-1));
    -    else
    -      Result := GetSpecialShortCutName(Key);
    -  end;
    -end;
    -
     function ShortCutToText(ShortCut: TShortCut): string;
     var
       Name: string;
    
    key2.diff (16,350 bytes)
  • key2fix.diff (17,046 bytes)
    Index: lcl/lclproc.pas
    ===================================================================
    --- lcl/lclproc.pas	(revision 53427)
    +++ lcl/lclproc.pas	(working copy)
    @@ -467,10 +467,278 @@
       MenuKeyCaps: array[TMenuKeyCap] of string;
       MenuKeyCapsInited: boolean = false;
     
    +const
    +  // MS documentation:
    +  // https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
    +  //
    +  // Note: ShortcutToText must ignore single key Ctrl, Alt, Shift, Win,
    +  // so these items have empty str here
    +  //
    +  KeyCodeStrings: array[1..$FF] of string = (
    +    'Mouse_Left', // 0x1 - VK_LBUTTON
    +    'Mouse_Right', // 0x2 - VK_RBUTTON
    +    'Cancel', // 0x3 - VK_CANCEL - generated by Ctrl+Break
    +    'Mouse_Middle', // 0x4 - VK_MBUTTON
    +    'Mouse_X1', // 0x5 - VK_XBUTTON1
    +    'Mouse_X2', // 0x6 - VK_XBUTTON2
    +    '', // 0x7
    +    'Backspace', // 0x8 - VK_BACK
    +    'Tab', // 0x9 - VK_TAB
    +    '', // 0xa
    +    '', // 0xb
    +    'NumClear', // 0xc - VK_CLEAR - generated by Num5 (NumLock off)
    +    'Enter', // 0xd - VK_RETURN
    +    '', // 0xe
    +    '', // 0xf
    +    '', //'Shift', // 0x10 - VK_SHIFT
    +    '', //'Ctrl', // 0x11 - VK_CONTROL
    +    '', //'Alt', // 0x12 - VK_MENU
    +    'Break', // 0x13 - VK_PAUSE - Pause/Break key
    +    'CapsLock', // 0x14 - VK_CAPITAL
    +    'IME_Kana', // 0x15 - VK_KANA
    +    '', // 0x16
    +    'IME_Junja', // 0x17 - VK_JUNJA
    +    'IME_final', // 0x18 - VK_FINAL
    +    'IME_Hanja', // 0x19 - VK_HANJA
    +    '', // 0x1a
    +    'Esc', // 0x1b - VK_ESCAPE
    +    'IME_convert', // 0x1c - VK_CONVERT
    +    'IME_nonconvert', // 0x1d - VK_NONCONVERT
    +    'IME_accept', // 0x1e - VK_ACCEPT
    +    'IME_mode_change', // 0x1f - VK_MODECHANGE
    +    'Space', // 0x20 - VK_SPACE
    +    'PgUp', // 0x21 - VK_PRIOR
    +    'PgDown', // 0x22 - VK_NEXT
    +    'End', // 0x23 - VK_END
    +    'Home', // 0x24 - VK_HOME
    +    'Left', // 0x25 - VK_LEFT
    +    'Up', // 0x26 - VK_UP
    +    'Right', // 0x27 - VK_RIGHT
    +    'Down', // 0x28 - VK_DOWN
    +    'Select', // 0x29 - VK_SELECT
    +    'Print', // 0x2a - VK_PRINT
    +    'Execute', // 0x2b - VK_EXECUTE
    +    'PrintScreen', // 0x2c - VK_SNAPSHOT
    +    'Ins', // 0x2d - VK_INSERT
    +    'Del', // 0x2e - VK_DELETE
    +    'Help', // 0x2f - VK_HELP
    +    '0', // 0x30
    +    '1', // 0x31
    +    '2', // 0x32
    +    '3', // 0x33
    +    '4', // 0x34
    +    '5', // 0x35
    +    '6', // 0x36
    +    '7', // 0x37
    +    '8', // 0x38
    +    '9', // 0x39
    +    '', // 0x3a
    +    '', // 0x3b
    +    '', // 0x3c
    +    '', // 0x3d
    +    '', // 0x3e
    +    '', // 0x3f
    +    '', // 0x40
    +    'A', // 0x41
    +    'B', // 0x42
    +    'C', // 0x43
    +    'D', // 0x44
    +    'E', // 0x45
    +    'F', // 0x46
    +    'G', // 0x47
    +    'H', // 0x48
    +    'I', // 0x49
    +    'J', // 0x4a
    +    'K', // 0x4b
    +    'L', // 0x4c
    +    'M', // 0x4d
    +    'N', // 0x4e
    +    'O', // 0x4f
    +    'P', // 0x50
    +    'Q', // 0x51
    +    'R', // 0x52
    +    'S', // 0x53
    +    'T', // 0x54
    +    'U', // 0x55
    +    'V', // 0x56
    +    'W', // 0x57
    +    'X', // 0x58
    +    'Y', // 0x59
    +    'Z', // 0x5a
    +    '', //'LWindows', // 0x5b - VK_LWIN
    +    '', //'RWindows', // 0x5c - VK_RWIN
    +    'PopUp', // 0x5d - VK_APPS - PC, key near right Ctrl
    +    '', // 0x5e
    +    'Sleep', // 0x5f - VK_SLEEP
    +    'Num0', // 0x60 - VK_NUMPAD0
    +    'Num1', // 0x61
    +    'Num2', // 0x62
    +    'Num3', // 0x63
    +    'Num4', // 0x64
    +    'Num5', // 0x65
    +    'Num6', // 0x66
    +    'Num7', // 0x67
    +    'Num8', // 0x68
    +    'Num9', // 0x69 - VK_NUMPAD9
    +    'NumMul', // 0x6a - VK_MULTIPLY
    +    'NumPlus', // 0x6b - VK_ADD
    +    'NumSepar', // 0x6c - VK_SEPARATOR
    +    'NumMinus', // 0x6d - VK_SUBTRACT
    +    'NumDot', // 0x6e - VK_DECIMAL
    +    'NumDiv', // 0x6f - VK_DIVIDE
    +    'F1', // 0x70 - VK_F1
    +    'F2', // 0x71
    +    'F3', // 0x72
    +    'F4', // 0x73
    +    'F5', // 0x74
    +    'F6', // 0x75
    +    'F7', // 0x76
    +    'F8', // 0x77
    +    'F9', // 0x78
    +    'F10', // 0x79
    +    'F11', // 0x7a
    +    'F12', // 0x7b
    +    'F13', // 0x7c
    +    'F14', // 0x7d
    +    'F15', // 0x7e
    +    'F16', // 0x7f
    +    'F17', // 0x80
    +    'F18', // 0x81
    +    'F19', // 0x82
    +    'F20', // 0x83
    +    'F21', // 0x84
    +    'F22', // 0x85
    +    'F23', // 0x86
    +    'F24', // 0x87 - VK_F24
    +    '', // 0x88
    +    '', // 0x89
    +    '', // 0x8a
    +    '', // 0x8b
    +    '', // 0x8c
    +    '', // 0x8d
    +    '', // 0x8e
    +    '', // 0x8f
    +    'NumLock', // 0x90 - VK_NUMLOCK
    +    'ScrollLock', // 0x91 - VK_SCROLL
    +    'OEM_0x92', // 0x92
    +    'OEM_0x93', // 0x93
    +    'OEM_0x94', // 0x94
    +    'OEM_0x95', // 0x95
    +    'OEM_0x96', // 0x96
    +    '', // 0x97
    +    '', // 0x98
    +    '', // 0x99
    +    '', // 0x9a
    +    '', // 0x9b
    +    '', // 0x9c
    +    '', // 0x9d
    +    '', // 0x9e
    +    '', // 0x9f
    +    '', //'LShift', // 0xa0 - VK_LSHIFT
    +    '', //'RShift', // 0xa1 - VK_RSHIFT
    +    '', //'LCtrl', // 0xa2 - VK_LCONTROL
    +    '', //'RCtrl', // 0xa3 - VK_RCONTROL
    +    '', //'LAlt', // 0xa4 - VK_LMENU
    +    '', //'RAlt', // 0xa5 - VK_RMENU
    +    'BrowserBack', // 0xa6 - VK_BROWSER_BACK
    +    'BrowserForward', // 0xa7 - VK_BROWSER_FORWARD
    +    'BrowserRefresh', // 0xa8 - VK_BROWSER_REFRESH
    +    'BrowserStop', // 0xa9 - VK_BROWSER_STOP
    +    'BrowserSearch', // 0xaa - VK_BROWSER_SEARCH
    +    'BrowserFav', // 0xab - VK_BROWSER_FAVORITES
    +    'BrowserHome', // 0xac - VK_BROWSER_HOME
    +    'VolumeMute', // 0xad - VK_VOLUME_MUTE
    +    'VolumeDown', // 0xae - VK_VOLUME_DOWN
    +    'VolumeUp', // 0xaf - VK_VOLUME_UP
    +    'MediaNext', // 0xb0 - VK_MEDIA_NEXT_TRACK
    +    'MediaPrev', // 0xb1 - VK_MEDIA_PREV_TRACK
    +    'MediaStop', // 0xb2 - VK_MEDIA_STOP
    +    'MediaPlayPause', // 0xb3 - VK_MEDIA_PLAY_PAUSE
    +    'LaunchMail', // 0xb4 - VK_LAUNCH_MAIL
    +    'LaunchMedia', // 0xb5 - VK_LAUNCH_MEDIA_SELECT
    +    'LaunchApp1', // 0xb6 - VK_LAUNCH_APP1
    +    'LaunchApp2', // 0xb7 - VK_LAUNCH_APP2
    +    '', // 0xb8
    +    '', // 0xb9
    +    ';', // 0xba - VK_OEM_1 - Can vary by keyboard, US keyboard, the ';:' key
    +    '+', // 0xbb - VK_OEM_PLUS - For any country/region, the '+' key
    +    ',', // 0xbc - VK_OEM_COMMA - For any country/region, the ',' key
    +    '-', // 0xbd - VK_OEM_MINUS - For any country/region, the '-' key
    +    '.', // 0xbe - VK_OEM_PERIOD - For any country/region, the '.' key
    +    '/', // 0xbf - VK_OEM_2 - Can vary by keyboard, US keyboard, the '/?' key
    +    '`', // 0xc0 - VK_OEM_3 - Can vary by keyboard, US keyboard, the '`~' key
    +    '', // 0xc1
    +    '', // 0xc2
    +    '', // 0xc3
    +    '', // 0xc4
    +    '', // 0xc5
    +    '', // 0xc6
    +    '', // 0xc7
    +    '', // 0xc8
    +    '', // 0xc9
    +    '', // 0xca
    +    '', // 0xcb
    +    '', // 0xcc
    +    '', // 0xcd
    +    '', // 0xce
    +    '', // 0xcf
    +    '', // 0xd0
    +    '', // 0xd1
    +    '', // 0xd2
    +    '', // 0xd3
    +    '', // 0xd4
    +    '', // 0xd5
    +    '', // 0xd6
    +    '', // 0xd7
    +    '', // 0xd8
    +    '', // 0xd9
    +    '', // 0xda
    +    '[', // 0xdb - VK_OEM_4 - Can vary by keyboard, US keyboard, the '[{' key
    +    '\', // 0xdc - VK_OEM_5 - Can vary by keyboard, US keyboard, the '\|' key
    +    ']', // 0xdd - VK_OEM_6 - Can vary by keyboard, US keyboard, the ']}' key
    +    '''', // 0xde - VK_OEM_7 - Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
    +    'OEM_8', // 0xdf - VK_OEM_8
    +    '', // 0xe0
    +    'OEM_0xE1', // 0xe1
    +    '\', // 0xe2 - VK_OEM_102 - Either the angle bracket key or the backslash key on the RT 102-key keyboard
    +    'OEM_0xE3', // 0xe3
    +    'OEM_0xE4', // 0xe4
    +    'IME_process', // 0xe5 - VK_PROCESSKEY
    +    'OEM_0xE6', // 0xe6
    +    'UnicodePacket', // 0xe7 - VK_PACKET
    +    '', // 0xe8
    +    'OEM_0xE9', // 0xe9
    +    'OEM_0xEA', // 0xea
    +    'OEM_0xEB', // 0xeb
    +    'OEM_0xEC', // 0xec
    +    'OEM_0xED', // 0xed
    +    'OEM_0xEE', // 0xee
    +    'OEM_0xEF', // 0xef
    +    'OEM_0xF0', // 0xf0
    +    'OEM_0xF1', // 0xf1
    +    'OEM_0xF2', // 0xf2
    +    'OEM_0xF3', // 0xf3
    +    'OEM_0xF4', // 0xf4
    +    'OEM_0xF5', // 0xf5
    +    'Attn', // 0xf6 - VK_ATTN
    +    'CrSel', // 0xf7 - VK_CRSEL
    +    'ExSel', // 0xf8 - VK_EXSEL
    +    'EraseEOF', // 0xf9 - VK_EREOF
    +    'Play', // 0xfa - VK_PLAY
    +    'Zoom', // 0xfb - VK_ZOOM
    +    '', // 0xfc
    +    'PA1', // 0xfd - VK_PA1
    +    'OEM_Clear', // 0xfe - VK_OEM_CLEAR
    +    '' // 0xff
    +  );
    +
    +
     procedure InitializeMenuKeyCaps;
     begin
    -  if MenuKeyCapsInited=false then
    +  if not MenuKeyCapsInited then
       begin
    +    MenuKeyCapsInited:=true;
    +
         MenuKeyCaps[mkcBkSp]:=SmkcBkSp;
         MenuKeyCaps[mkcTab]:=SmkcTab;
         MenuKeyCaps[mkcEsc]:=SmkcEsc;
    @@ -490,58 +758,26 @@
         MenuKeyCaps[mkcCtrl]:=SmkcCtrl;
         MenuKeyCaps[mkcAlt]:=SmkcAlt;
         MenuKeyCaps[mkcMeta]:=SmkcMeta;
    -    MenuKeyCapsInited:=true;
    -  end;
    -end;
     
    -function GetSpecialShortCutName(Key: integer): string;
    -begin
    -  Result := '';
    -  case Key of
    -    VK_CANCEL:     Result := 'Cancel'; //generated by Ctrl+Break
    -    VK_CLEAR:      Result := 'NumClear'; //generated by Num5 (NumLock off)
    -    VK_PAUSE:      Result := 'Break';
    -    VK_CAPITAL:    Result := 'CapsLock';
    -    VK_APPS:       Result := 'PopUp'; //PC, near right Ctrl
    -    VK_MULTIPLY:   Result := 'NumMul';
    -    VK_ADD:        Result := 'NumPlus';
    -    VK_SUBTRACT:   Result := 'NumMinus';
    -    VK_DECIMAL:    Result := 'NumDot';
    -    VK_DIVIDE:     Result := 'NumDiv';
    -    VK_NUMLOCK:    Result := 'NumLock';
    -    VK_SCROLL:     Result := 'ScrollLock';
    -    VK_OEM_1:      Result := ';'; // Can vary by keyboard, US keyboard, the ';:' key
    -    VK_OEM_PLUS:   Result := '+'; // For any country/region, the '+' key
    -    VK_OEM_COMMA:  Result := ','; // For any country/region, the ',' key
    -    VK_OEM_MINUS:  Result := '-'; // For any country/region, the '-' key
    -    VK_OEM_PERIOD: Result := '.'; // For any country/region, the '.' key
    -    VK_OEM_2:      Result := '/'; // Can vary by keyboard, US keyboard, the '/?' key
    -    VK_OEM_3:      Result := '`'; // Can vary by keyboard, US keyboard, the '`~' key
    -    VK_OEM_4:      Result := '['; // Can vary by keyboard, US keyboard, the '[{' key
    -    VK_OEM_5:      Result := '\'; // Can vary by keyboard, US keyboard, the '\|' key
    -    VK_OEM_6:      Result := ']'; // Can vary by keyboard, US keyboard, the ']}' key
    -    VK_OEM_7:      Result := ''''; // Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
    -    VK_OEM_102:    Result := '\'; // Either the angle bracket key or the backslash key on the RT 102-key keyboard
    -
    -    //Windows keyboard special:
    -    $A6: Result := 'BrowserBack';
    -    $A7: Result := 'BrowserForward';
    -    $A8: Result := 'BrowserRefresh';
    -    $A9: Result := 'BrowserStop';
    -    $AA: Result := 'BrowserSearch';
    -    $AB: Result := 'BrowserFav';
    -    $AC: Result := 'BrowserHome';
    -    $AD: Result := 'VolumeMute';
    -    $AE: Result := 'VolumeDown';
    -    $AF: Result := 'VolumeUp';
    -    $B0: Result := 'MediaNext';
    -    $B1: Result := 'MediaPrev';
    -    $B2: Result := 'MediaStop';
    -    $B3: Result := 'MediaPlay';
    -    $B4: Result := 'LaunchMail';
    -    $B5: Result := 'LaunchMedia';
    -    $B6: Result := 'LaunchApp1';
    -    $B7: Result := 'LaunchApp2';
    +    KeyCodeStrings[VK_BACK]:=SmkcBkSp;
    +    KeyCodeStrings[VK_TAB]:=SmkcTab;
    +    KeyCodeStrings[VK_ESCAPE]:=SmkcEsc;
    +    KeyCodeStrings[VK_RETURN]:=SmkcEnter;
    +    KeyCodeStrings[VK_SPACE]:=SmkcSpace;
    +    KeyCodeStrings[VK_PRIOR]:=SmkcPgUp;
    +    KeyCodeStrings[VK_NEXT]:=SmkcPgDn;
    +    KeyCodeStrings[VK_END]:=SmkcEnd;
    +    KeyCodeStrings[VK_HOME]:=SmkcHome;
    +    KeyCodeStrings[VK_LEFT]:=SmkcLeft;
    +    KeyCodeStrings[VK_UP]:=SmkcUp;
    +    KeyCodeStrings[VK_RIGHT]:=SmkcRight;
    +    KeyCodeStrings[VK_DOWN]:=SmkcDown;
    +    KeyCodeStrings[VK_INSERT]:=SmkcIns;
    +    KeyCodeStrings[VK_DELETE]:=SmkcDel;
    +    // must ignore single Shift, Alt, Ctrl in KeyCodeStrings
    +    //KeyCodeStrings[VK_SHIFT]:=SmkcShift;
    +    //KeyCodeStrings[VK_CONTROL]:=SmkcCtrl;
    +    //KeyCodeStrings[VK_MENU]:=SmkcAlt;
       end;
     end;
     
    @@ -575,6 +811,14 @@
         Result:=DefaultValue;
     end;
     
    +function KeyCodeToKeyString(Key: integer): string;
    +begin
    +  if (Key>=Low(KeyCodeStrings)) and (Key<=High(KeyCodeStrings)) then
    +    Result := KeyCodeStrings[Key]
    +  else
    +    Result := '';
    +end;
    +
     // Used also by TWidgetSet.GetAcceleratorString
     function KeyAndShiftStateToKeyString(Key: word; ShiftState: TShiftState): String;
     
    @@ -585,79 +829,8 @@
         Result := Result + APart;
       end;
     
    -  // Tricky routine. This only works for western languages
    -  procedure AddKey;
    -  begin
    -    case Key of
    -      VK_UNKNOWN    :AddPart(ifsVK_UNKNOWN);
    -      VK_LBUTTON    :AddPart(ifsVK_LBUTTON);
    -      VK_RBUTTON    :AddPart(ifsVK_RBUTTON);
    -      VK_CANCEL     :AddPart(ifsVK_CANCEL);
    -      VK_MBUTTON    :AddPart(ifsVK_MBUTTON);
    -      VK_BACK       :AddPart(ifsVK_BACK);
    -      VK_TAB        :AddPart(ifsVK_TAB);
    -      VK_CLEAR      :AddPart(ifsVK_CLEAR);
    -      VK_RETURN     :AddPart(ifsVK_RETURN);
    -      VK_SHIFT      :AddPart(ifsVK_SHIFT);
    -      VK_CONTROL    :AddPart(ifsVK_CONTROL);
    -      VK_MENU       :AddPart(ifsVK_MENU);
    -      VK_PAUSE      :AddPart(ifsVK_PAUSE);
    -      VK_CAPITAL    :AddPart(ifsVK_CAPITAL);
    -      VK_KANA       :AddPart(ifsVK_KANA);
    -    //  VK_HANGUL     :AddPart('Hangul');
    -      VK_JUNJA      :AddPart(ifsVK_JUNJA);
    -      VK_FINAL      :AddPart(ifsVK_FINAL);
    -      VK_HANJA      :AddPart(ifsVK_HANJA );
    -    //  VK_KANJI      :AddPart('Kanji');
    -      VK_ESCAPE     :AddPart(ifsVK_ESCAPE);
    -      VK_CONVERT    :AddPart(ifsVK_CONVERT);
    -      VK_NONCONVERT :AddPart(ifsVK_NONCONVERT);
    -      VK_ACCEPT     :AddPart(ifsVK_ACCEPT);
    -      VK_MODECHANGE :AddPart(ifsVK_MODECHANGE);
    -      VK_SPACE      :AddPart(ifsVK_SPACE);
    -      VK_PRIOR      :AddPart(ifsVK_PRIOR);
    -      VK_NEXT       :AddPart(ifsVK_NEXT);
    -      VK_END        :AddPart(ifsVK_END);
    -      VK_HOME       :AddPart(ifsVK_HOME);
    -      VK_LEFT       :AddPart(ifsVK_LEFT);
    -      VK_UP         :AddPart(ifsVK_UP);
    -      VK_RIGHT      :AddPart(ifsVK_RIGHT);
    -      VK_DOWN       :AddPart(ifsVK_DOWN);
    -      VK_SELECT     :AddPart(ifsVK_SELECT);
    -      VK_PRINT      :AddPart(ifsVK_PRINT);
    -      VK_EXECUTE    :AddPart(ifsVK_EXECUTE);
    -      VK_SNAPSHOT   :AddPart(ifsVK_SNAPSHOT);
    -      VK_INSERT     :AddPart(ifsVK_INSERT);
    -      VK_DELETE     :AddPart(ifsVK_DELETE);
    -      VK_HELP       :AddPart(ifsVK_HELP);
    -      VK_0..VK_9    :AddPart(chr(ord('0')+Key-VK_0));
    -      VK_A..VK_Z    :AddPart(chr(ord('A')+Key-VK_A));
    -      VK_LWIN       :AddPart(ifsVK_LWIN);
    -      VK_RWIN       :AddPart(ifsVK_RWIN);
    -      VK_APPS       :AddPart(ifsVK_APPS);
    -      VK_NUMPAD0..VK_NUMPAD9:  AddPart(Format(ifsVK_NUMPAD,[Key-VK_NUMPAD0]));
    -      VK_MULTIPLY   :AddPart('*');
    -      VK_ADD        :AddPart('+');
    -      VK_OEM_PLUS   :AddPart('+');
    -      VK_SEPARATOR  :AddPart('|');
    -      VK_SUBTRACT   :AddPart('-');
    -      VK_OEM_MINUS  :AddPart('-');
    -      VK_DECIMAL    :AddPart('.');
    -      VK_OEM_PERIOD :AddPart('.');
    -      VK_OEM_COMMA  :AddPart(',');
    -      VK_DIVIDE     :AddPart('/');
    -      VK_F1..VK_F24: AddPart('F'+IntToStr(Key-VK_F1+1));
    -      VK_NUMLOCK    :AddPart(ifsVK_NUMLOCK);
    -      VK_SCROLL     :AddPart(ifsVK_SCROLL);
    -      VK_OEM_2      :AddPart('OEM2');
    -      VK_OEM_3      :AddPart('OEM3');
    -//    VK_EQUAL      :AddPart('=');
    -//    VK_AT         :AddPart('@');
    -    else
    -      AddPart(UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX);
    -    end;
    -  end;
    -
    +var
    +  S: string;
     begin
       Result := '';
       if ssCtrl in ShiftState then AddPart(ifsCtrl);
    @@ -670,7 +843,12 @@
         AddPart(ifsVK_META);
         {$ENDIF}
       if ssSuper in ShiftState then AddPart(ifsVK_SUPER);
    -  AddKey;
    +
    +  S := KeyCodeToKeyString(Key);
    +  // function returned "Word(nnn)" previously, keep this
    +  if S='' then
    +    S := UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX;
    +  AddPart(S);
     end;
     
     function KeyStringIsIrregular(const s: string): boolean;
    @@ -679,36 +857,6 @@
         (AnsiStrLComp(PChar(s),PChar(UNKNOWN_VK_PREFIX),length(UNKNOWN_VK_PREFIX))=0);
     end;
     
    -function KeyCodeToKeyString(Key: integer): string;
    -begin
    -  case Key of
    -    VK_BACK:
    -      Result := MenuKeyCaps[mkcBkSp];
    -    VK_TAB:
    -      Result := MenuKeyCaps[mkcTab];
    -    VK_RETURN:
    -      Result := MenuKeyCaps[mkcEnter];
    -    VK_ESCAPE:
    -      Result := MenuKeyCaps[mkcEsc];
    -    VK_SPACE..VK_SPACE+8:
    -      Result := MenuKeyCaps[TMenuKeyCap(Key - VK_SPACE + Ord(mkcSpace))];
    -    VK_INSERT:
    -      Result := MenuKeyCaps[mkcIns];
    -    VK_DELETE:
    -      Result := MenuKeyCaps[mkcDel];
    -    VK_0..VK_9:
    -      Result := Chr(Key - VK_0 + Ord('0'));
    -    VK_A..VK_Z:
    -      Result := Chr(Key - VK_A + Ord('A'));
    -    VK_NUMPAD0..VK_NUMPAD9:
    -      Result := 'Num' + Chr(Key - VK_NUMPAD0 + Ord('0')); // Delphi differs it from 0..9
    -    VK_F1..VK_F24:
    -      Result := 'F' + IntToStr(Key - (VK_F1-1));
    -    else
    -      Result := GetSpecialShortCutName(Key);
    -  end;
    -end;
    -
     function ShortCutToText(ShortCut: TShortCut): string;
     var
       Name: string;
    @@ -765,8 +913,10 @@
         else
           Break;
       end;
    -  for Key := $08 to $FF do begin { Copy range from table in ShortCutToText }
    -    Name := ShortCutToText(Key);
    +
    +  for Key := Low(KeyCodeStrings) to High(KeyCodeStrings) do
    +  begin
    +    Name := KeyCodeToKeyString(Key);
         if (Name<>'') and (length(Name)=length(ShortCutText)-StartPos+1)
         and (AnsiStrLIComp(@ShortCutText[StartPos], PChar(Name), length(Name)) = 0)
         then begin
    
    key2fix.diff (17,046 bytes)
  • test.zip (558 bytes)

Relationships

related to 0030988 resolvedMattias Gaertner Patches Refact ShortcutToText 
related to 0030973 resolvedJuha Manninen Lazarus False display of shortcut + for menus 
related to 0023082 closedMaxim Ganetsky Lazarus Shortcuts and i18n 
related to 0034045 closedMaxim Ganetsky Lazarus Translation of keyboard shortcuts does not change when language is switched 

Activities

CudaText man

2016-11-23 18:19

reporter  

key2.diff (16,350 bytes)
Index: lcl/lclproc.pas
===================================================================
--- lcl/lclproc.pas	(revision 53427)
+++ lcl/lclproc.pas	(working copy)
@@ -467,10 +467,275 @@
   MenuKeyCaps: array[TMenuKeyCap] of string;
   MenuKeyCapsInited: boolean = false;
 
+const
+  // MS documentation:
+  // https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
+  //
+  KeyCodeStrings: array[1..$FF] of string = (
+    'Mouse_Left', // 0x1 - VK_LBUTTON
+    'Mouse_Right', // 0x2 - VK_RBUTTON
+    'Cancel', // 0x3 - VK_CANCEL - generated by Ctrl+Break
+    'Mouse_Middle', // 0x4 - VK_MBUTTON
+    'Mouse_X1', // 0x5 - VK_XBUTTON1
+    'Mouse_X2', // 0x6 - VK_XBUTTON2
+    '', // 0x7
+    'Backspace', // 0x8 - VK_BACK
+    'Tab', // 0x9 - VK_TAB
+    '', // 0xa
+    '', // 0xb
+    'NumClear', // 0xc - VK_CLEAR - generated by Num5 (NumLock off)
+    'Enter', // 0xd - VK_RETURN
+    '', // 0xe
+    '', // 0xf
+    'Shift', // 0x10 - VK_SHIFT
+    'Ctrl', // 0x11 - VK_CONTROL
+    'Alt', // 0x12 - VK_MENU
+    'Break', // 0x13 - VK_PAUSE - Pause/Break key
+    'CapsLock', // 0x14 - VK_CAPITAL
+    'IME_Kana', // 0x15 - VK_KANA
+    '', // 0x16
+    'IME_Junja', // 0x17 - VK_JUNJA
+    'IME_final', // 0x18 - VK_FINAL
+    'IME_Hanja', // 0x19 - VK_HANJA
+    '', // 0x1a
+    'Esc', // 0x1b - VK_ESCAPE
+    'IME_convert', // 0x1c - VK_CONVERT
+    'IME_nonconvert', // 0x1d - VK_NONCONVERT
+    'IME_accept', // 0x1e - VK_ACCEPT
+    'IME_mode_change', // 0x1f - VK_MODECHANGE
+    'Space', // 0x20 - VK_SPACE
+    'PgUp', // 0x21 - VK_PRIOR
+    'PgDown', // 0x22 - VK_NEXT
+    'End', // 0x23 - VK_END
+    'Home', // 0x24 - VK_HOME
+    'Left', // 0x25 - VK_LEFT
+    'Up', // 0x26 - VK_UP
+    'Right', // 0x27 - VK_RIGHT
+    'Down', // 0x28 - VK_DOWN
+    'Select', // 0x29 - VK_SELECT
+    'Print', // 0x2a - VK_PRINT
+    'Execute', // 0x2b - VK_EXECUTE
+    'PrintScreen', // 0x2c - VK_SNAPSHOT
+    'Ins', // 0x2d - VK_INSERT
+    'Del', // 0x2e - VK_DELETE
+    'Help', // 0x2f - VK_HELP
+    '0', // 0x30
+    '1', // 0x31
+    '2', // 0x32
+    '3', // 0x33
+    '4', // 0x34
+    '5', // 0x35
+    '6', // 0x36
+    '7', // 0x37
+    '8', // 0x38
+    '9', // 0x39
+    '', // 0x3a
+    '', // 0x3b
+    '', // 0x3c
+    '', // 0x3d
+    '', // 0x3e
+    '', // 0x3f
+    '', // 0x40
+    'A', // 0x41
+    'B', // 0x42
+    'C', // 0x43
+    'D', // 0x44
+    'E', // 0x45
+    'F', // 0x46
+    'G', // 0x47
+    'H', // 0x48
+    'I', // 0x49
+    'J', // 0x4a
+    'K', // 0x4b
+    'L', // 0x4c
+    'M', // 0x4d
+    'N', // 0x4e
+    'O', // 0x4f
+    'P', // 0x50
+    'Q', // 0x51
+    'R', // 0x52
+    'S', // 0x53
+    'T', // 0x54
+    'U', // 0x55
+    'V', // 0x56
+    'W', // 0x57
+    'X', // 0x58
+    'Y', // 0x59
+    'Z', // 0x5a
+    'LWindows', // 0x5b - VK_LWIN
+    'RWindows', // 0x5c - VK_RWIN
+    'PopUp', // 0x5d - VK_APPS - PC, key near right Ctrl
+    '', // 0x5e
+    'Sleep', // 0x5f - VK_SLEEP
+    'Num0', // 0x60 - VK_NUMPAD0
+    'Num1', // 0x61
+    'Num2', // 0x62
+    'Num3', // 0x63
+    'Num4', // 0x64
+    'Num5', // 0x65
+    'Num6', // 0x66
+    'Num7', // 0x67
+    'Num8', // 0x68
+    'Num9', // 0x69 - VK_NUMPAD9
+    'NumMul', // 0x6a - VK_MULTIPLY
+    'NumPlus', // 0x6b - VK_ADD
+    'NumSepar', // 0x6c - VK_SEPARATOR
+    'NumMinus', // 0x6d - VK_SUBTRACT
+    'NumDot', // 0x6e - VK_DECIMAL
+    'NumDiv', // 0x6f - VK_DIVIDE
+    'F1', // 0x70 - VK_F1
+    'F2', // 0x71
+    'F3', // 0x72
+    'F4', // 0x73
+    'F5', // 0x74
+    'F6', // 0x75
+    'F7', // 0x76
+    'F8', // 0x77
+    'F9', // 0x78
+    'F10', // 0x79
+    'F11', // 0x7a
+    'F12', // 0x7b
+    'F13', // 0x7c
+    'F14', // 0x7d
+    'F15', // 0x7e
+    'F16', // 0x7f
+    'F17', // 0x80
+    'F18', // 0x81
+    'F19', // 0x82
+    'F20', // 0x83
+    'F21', // 0x84
+    'F22', // 0x85
+    'F23', // 0x86
+    'F24', // 0x87 - VK_F24
+    '', // 0x88
+    '', // 0x89
+    '', // 0x8a
+    '', // 0x8b
+    '', // 0x8c
+    '', // 0x8d
+    '', // 0x8e
+    '', // 0x8f
+    'NumLock', // 0x90 - VK_NUMLOCK
+    'ScrollLock', // 0x91 - VK_SCROLL
+    'OEM_0x92', // 0x92
+    'OEM_0x93', // 0x93
+    'OEM_0x94', // 0x94
+    'OEM_0x95', // 0x95
+    'OEM_0x96', // 0x96
+    '', // 0x97
+    '', // 0x98
+    '', // 0x99
+    '', // 0x9a
+    '', // 0x9b
+    '', // 0x9c
+    '', // 0x9d
+    '', // 0x9e
+    '', // 0x9f
+    'LShift', // 0xa0 - VK_LSHIFT
+    'RShift', // 0xa1 - VK_RSHIFT
+    'LCtrl', // 0xa2 - VK_LCONTROL
+    'RCtrl', // 0xa3 - VK_RCONTROL
+    'LAlt', // 0xa4 - VK_LMENU
+    'RAlt', // 0xa5 - VK_RMENU
+    'BrowserBack', // 0xa6 - VK_BROWSER_BACK
+    'BrowserForward', // 0xa7 - VK_BROWSER_FORWARD
+    'BrowserRefresh', // 0xa8 - VK_BROWSER_REFRESH
+    'BrowserStop', // 0xa9 - VK_BROWSER_STOP
+    'BrowserSearch', // 0xaa - VK_BROWSER_SEARCH
+    'BrowserFav', // 0xab - VK_BROWSER_FAVORITES
+    'BrowserHome', // 0xac - VK_BROWSER_HOME
+    'VolumeMute', // 0xad - VK_VOLUME_MUTE
+    'VolumeDown', // 0xae - VK_VOLUME_DOWN
+    'VolumeUp', // 0xaf - VK_VOLUME_UP
+    'MediaNext', // 0xb0 - VK_MEDIA_NEXT_TRACK
+    'MediaPrev', // 0xb1 - VK_MEDIA_PREV_TRACK
+    'MediaStop', // 0xb2 - VK_MEDIA_STOP
+    'MediaPlayPause', // 0xb3 - VK_MEDIA_PLAY_PAUSE
+    'LaunchMail', // 0xb4 - VK_LAUNCH_MAIL
+    'LaunchMedia', // 0xb5 - VK_LAUNCH_MEDIA_SELECT
+    'LaunchApp1', // 0xb6 - VK_LAUNCH_APP1
+    'LaunchApp2', // 0xb7 - VK_LAUNCH_APP2
+    '', // 0xb8
+    '', // 0xb9
+    ';', // 0xba - VK_OEM_1 - Can vary by keyboard, US keyboard, the ';:' key
+    '+', // 0xbb - VK_OEM_PLUS - For any country/region, the '+' key
+    ',', // 0xbc - VK_OEM_COMMA - For any country/region, the ',' key
+    '-', // 0xbd - VK_OEM_MINUS - For any country/region, the '-' key
+    '.', // 0xbe - VK_OEM_PERIOD - For any country/region, the '.' key
+    '/', // 0xbf - VK_OEM_2 - Can vary by keyboard, US keyboard, the '/?' key
+    '`', // 0xc0 - VK_OEM_3 - Can vary by keyboard, US keyboard, the '`~' key
+    '', // 0xc1
+    '', // 0xc2
+    '', // 0xc3
+    '', // 0xc4
+    '', // 0xc5
+    '', // 0xc6
+    '', // 0xc7
+    '', // 0xc8
+    '', // 0xc9
+    '', // 0xca
+    '', // 0xcb
+    '', // 0xcc
+    '', // 0xcd
+    '', // 0xce
+    '', // 0xcf
+    '', // 0xd0
+    '', // 0xd1
+    '', // 0xd2
+    '', // 0xd3
+    '', // 0xd4
+    '', // 0xd5
+    '', // 0xd6
+    '', // 0xd7
+    '', // 0xd8
+    '', // 0xd9
+    '', // 0xda
+    '[', // 0xdb - VK_OEM_4 - Can vary by keyboard, US keyboard, the '[{' key
+    '\', // 0xdc - VK_OEM_5 - Can vary by keyboard, US keyboard, the '\|' key
+    ']', // 0xdd - VK_OEM_6 - Can vary by keyboard, US keyboard, the ']}' key
+    '''', // 0xde - VK_OEM_7 - Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
+    'OEM_8', // 0xdf - VK_OEM_8
+    '', // 0xe0
+    'OEM_0xE1', // 0xe1
+    '\', // 0xe2 - VK_OEM_102 - Either the angle bracket key or the backslash key on the RT 102-key keyboard
+    'OEM_0xE3', // 0xe3
+    'OEM_0xE4', // 0xe4
+    'IME_process', // 0xe5 - VK_PROCESSKEY
+    'OEM_0xE6', // 0xe6
+    'UnicodePacket', // 0xe7 - VK_PACKET
+    '', // 0xe8
+    'OEM_0xE9', // 0xe9
+    'OEM_0xEA', // 0xea
+    'OEM_0xEB', // 0xeb
+    'OEM_0xEC', // 0xec
+    'OEM_0xED', // 0xed
+    'OEM_0xEE', // 0xee
+    'OEM_0xEF', // 0xef
+    'OEM_0xF0', // 0xf0
+    'OEM_0xF1', // 0xf1
+    'OEM_0xF2', // 0xf2
+    'OEM_0xF3', // 0xf3
+    'OEM_0xF4', // 0xf4
+    'OEM_0xF5', // 0xf5
+    'Attn', // 0xf6 - VK_ATTN
+    'CrSel', // 0xf7 - VK_CRSEL
+    'ExSel', // 0xf8 - VK_EXSEL
+    'EraseEOF', // 0xf9 - VK_EREOF
+    'Play', // 0xfa - VK_PLAY
+    'Zoom', // 0xfb - VK_ZOOM
+    '', // 0xfc
+    'PA1', // 0xfd - VK_PA1
+    'OEM_Clear', // 0xfe - VK_OEM_CLEAR
+    '' // 0xff
+  );
+
+
 procedure InitializeMenuKeyCaps;
 begin
-  if MenuKeyCapsInited=false then
+  if not MenuKeyCapsInited then
   begin
+    MenuKeyCapsInited:=true;
+
     MenuKeyCaps[mkcBkSp]:=SmkcBkSp;
     MenuKeyCaps[mkcTab]:=SmkcTab;
     MenuKeyCaps[mkcEsc]:=SmkcEsc;
@@ -490,58 +755,25 @@
     MenuKeyCaps[mkcCtrl]:=SmkcCtrl;
     MenuKeyCaps[mkcAlt]:=SmkcAlt;
     MenuKeyCaps[mkcMeta]:=SmkcMeta;
-    MenuKeyCapsInited:=true;
-  end;
-end;
 
-function GetSpecialShortCutName(Key: integer): string;
-begin
-  Result := '';
-  case Key of
-    VK_CANCEL:     Result := 'Cancel'; //generated by Ctrl+Break
-    VK_CLEAR:      Result := 'NumClear'; //generated by Num5 (NumLock off)
-    VK_PAUSE:      Result := 'Break';
-    VK_CAPITAL:    Result := 'CapsLock';
-    VK_APPS:       Result := 'PopUp'; //PC, near right Ctrl
-    VK_MULTIPLY:   Result := 'NumMul';
-    VK_ADD:        Result := 'NumPlus';
-    VK_SUBTRACT:   Result := 'NumMinus';
-    VK_DECIMAL:    Result := 'NumDot';
-    VK_DIVIDE:     Result := 'NumDiv';
-    VK_NUMLOCK:    Result := 'NumLock';
-    VK_SCROLL:     Result := 'ScrollLock';
-    VK_OEM_1:      Result := ';'; // Can vary by keyboard, US keyboard, the ';:' key
-    VK_OEM_PLUS:   Result := '+'; // For any country/region, the '+' key
-    VK_OEM_COMMA:  Result := ','; // For any country/region, the ',' key
-    VK_OEM_MINUS:  Result := '-'; // For any country/region, the '-' key
-    VK_OEM_PERIOD: Result := '.'; // For any country/region, the '.' key
-    VK_OEM_2:      Result := '/'; // Can vary by keyboard, US keyboard, the '/?' key
-    VK_OEM_3:      Result := '`'; // Can vary by keyboard, US keyboard, the '`~' key
-    VK_OEM_4:      Result := '['; // Can vary by keyboard, US keyboard, the '[{' key
-    VK_OEM_5:      Result := '\'; // Can vary by keyboard, US keyboard, the '\|' key
-    VK_OEM_6:      Result := ']'; // Can vary by keyboard, US keyboard, the ']}' key
-    VK_OEM_7:      Result := ''''; // Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
-    VK_OEM_102:    Result := '\'; // Either the angle bracket key or the backslash key on the RT 102-key keyboard
-
-    //Windows keyboard special:
-    $A6: Result := 'BrowserBack';
-    $A7: Result := 'BrowserForward';
-    $A8: Result := 'BrowserRefresh';
-    $A9: Result := 'BrowserStop';
-    $AA: Result := 'BrowserSearch';
-    $AB: Result := 'BrowserFav';
-    $AC: Result := 'BrowserHome';
-    $AD: Result := 'VolumeMute';
-    $AE: Result := 'VolumeDown';
-    $AF: Result := 'VolumeUp';
-    $B0: Result := 'MediaNext';
-    $B1: Result := 'MediaPrev';
-    $B2: Result := 'MediaStop';
-    $B3: Result := 'MediaPlay';
-    $B4: Result := 'LaunchMail';
-    $B5: Result := 'LaunchMedia';
-    $B6: Result := 'LaunchApp1';
-    $B7: Result := 'LaunchApp2';
+    KeyCodeStrings[VK_BACK]:=SmkcBkSp;
+    KeyCodeStrings[VK_TAB]:=SmkcTab;
+    KeyCodeStrings[VK_ESCAPE]:=SmkcEsc;
+    KeyCodeStrings[VK_RETURN]:=SmkcEnter;
+    KeyCodeStrings[VK_SPACE]:=SmkcSpace;
+    KeyCodeStrings[VK_PRIOR]:=SmkcPgUp;
+    KeyCodeStrings[VK_NEXT]:=SmkcPgDn;
+    KeyCodeStrings[VK_END]:=SmkcEnd;
+    KeyCodeStrings[VK_HOME]:=SmkcHome;
+    KeyCodeStrings[VK_LEFT]:=SmkcLeft;
+    KeyCodeStrings[VK_UP]:=SmkcUp;
+    KeyCodeStrings[VK_RIGHT]:=SmkcRight;
+    KeyCodeStrings[VK_DOWN]:=SmkcDown;
+    KeyCodeStrings[VK_INSERT]:=SmkcIns;
+    KeyCodeStrings[VK_DELETE]:=SmkcDel;
+    KeyCodeStrings[VK_SHIFT]:=SmkcShift;
+    KeyCodeStrings[VK_CONTROL]:=SmkcCtrl;
+    KeyCodeStrings[VK_MENU]:=SmkcAlt;
   end;
 end;
 
@@ -575,6 +807,14 @@
     Result:=DefaultValue;
 end;
 
+function KeyCodeToKeyString(Key: integer): string;
+begin
+  if (Key>=Low(KeyCodeStrings)) and (Key<=High(KeyCodeStrings)) then
+    Result := KeyCodeStrings[Key]
+  else
+    Result := '';
+end;
+
 // Used also by TWidgetSet.GetAcceleratorString
 function KeyAndShiftStateToKeyString(Key: word; ShiftState: TShiftState): String;
 
@@ -585,79 +825,8 @@
     Result := Result + APart;
   end;
 
-  // Tricky routine. This only works for western languages
-  procedure AddKey;
-  begin
-    case Key of
-      VK_UNKNOWN    :AddPart(ifsVK_UNKNOWN);
-      VK_LBUTTON    :AddPart(ifsVK_LBUTTON);
-      VK_RBUTTON    :AddPart(ifsVK_RBUTTON);
-      VK_CANCEL     :AddPart(ifsVK_CANCEL);
-      VK_MBUTTON    :AddPart(ifsVK_MBUTTON);
-      VK_BACK       :AddPart(ifsVK_BACK);
-      VK_TAB        :AddPart(ifsVK_TAB);
-      VK_CLEAR      :AddPart(ifsVK_CLEAR);
-      VK_RETURN     :AddPart(ifsVK_RETURN);
-      VK_SHIFT      :AddPart(ifsVK_SHIFT);
-      VK_CONTROL    :AddPart(ifsVK_CONTROL);
-      VK_MENU       :AddPart(ifsVK_MENU);
-      VK_PAUSE      :AddPart(ifsVK_PAUSE);
-      VK_CAPITAL    :AddPart(ifsVK_CAPITAL);
-      VK_KANA       :AddPart(ifsVK_KANA);
-    //  VK_HANGUL     :AddPart('Hangul');
-      VK_JUNJA      :AddPart(ifsVK_JUNJA);
-      VK_FINAL      :AddPart(ifsVK_FINAL);
-      VK_HANJA      :AddPart(ifsVK_HANJA );
-    //  VK_KANJI      :AddPart('Kanji');
-      VK_ESCAPE     :AddPart(ifsVK_ESCAPE);
-      VK_CONVERT    :AddPart(ifsVK_CONVERT);
-      VK_NONCONVERT :AddPart(ifsVK_NONCONVERT);
-      VK_ACCEPT     :AddPart(ifsVK_ACCEPT);
-      VK_MODECHANGE :AddPart(ifsVK_MODECHANGE);
-      VK_SPACE      :AddPart(ifsVK_SPACE);
-      VK_PRIOR      :AddPart(ifsVK_PRIOR);
-      VK_NEXT       :AddPart(ifsVK_NEXT);
-      VK_END        :AddPart(ifsVK_END);
-      VK_HOME       :AddPart(ifsVK_HOME);
-      VK_LEFT       :AddPart(ifsVK_LEFT);
-      VK_UP         :AddPart(ifsVK_UP);
-      VK_RIGHT      :AddPart(ifsVK_RIGHT);
-      VK_DOWN       :AddPart(ifsVK_DOWN);
-      VK_SELECT     :AddPart(ifsVK_SELECT);
-      VK_PRINT      :AddPart(ifsVK_PRINT);
-      VK_EXECUTE    :AddPart(ifsVK_EXECUTE);
-      VK_SNAPSHOT   :AddPart(ifsVK_SNAPSHOT);
-      VK_INSERT     :AddPart(ifsVK_INSERT);
-      VK_DELETE     :AddPart(ifsVK_DELETE);
-      VK_HELP       :AddPart(ifsVK_HELP);
-      VK_0..VK_9    :AddPart(chr(ord('0')+Key-VK_0));
-      VK_A..VK_Z    :AddPart(chr(ord('A')+Key-VK_A));
-      VK_LWIN       :AddPart(ifsVK_LWIN);
-      VK_RWIN       :AddPart(ifsVK_RWIN);
-      VK_APPS       :AddPart(ifsVK_APPS);
-      VK_NUMPAD0..VK_NUMPAD9:  AddPart(Format(ifsVK_NUMPAD,[Key-VK_NUMPAD0]));
-      VK_MULTIPLY   :AddPart('*');
-      VK_ADD        :AddPart('+');
-      VK_OEM_PLUS   :AddPart('+');
-      VK_SEPARATOR  :AddPart('|');
-      VK_SUBTRACT   :AddPart('-');
-      VK_OEM_MINUS  :AddPart('-');
-      VK_DECIMAL    :AddPart('.');
-      VK_OEM_PERIOD :AddPart('.');
-      VK_OEM_COMMA  :AddPart(',');
-      VK_DIVIDE     :AddPart('/');
-      VK_F1..VK_F24: AddPart('F'+IntToStr(Key-VK_F1+1));
-      VK_NUMLOCK    :AddPart(ifsVK_NUMLOCK);
-      VK_SCROLL     :AddPart(ifsVK_SCROLL);
-      VK_OEM_2      :AddPart('OEM2');
-      VK_OEM_3      :AddPart('OEM3');
-//    VK_EQUAL      :AddPart('=');
-//    VK_AT         :AddPart('@');
-    else
-      AddPart(UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX);
-    end;
-  end;
-
+var
+  S: string;
 begin
   Result := '';
   if ssCtrl in ShiftState then AddPart(ifsCtrl);
@@ -670,7 +839,12 @@
     AddPart(ifsVK_META);
     {$ENDIF}
   if ssSuper in ShiftState then AddPart(ifsVK_SUPER);
-  AddKey;
+
+  S := KeyCodeToKeyString(Key);
+  // function returned "Word(nnn)" previously, keep this
+  if S='' then
+    S := UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX;
+  AddPart(S);
 end;
 
 function KeyStringIsIrregular(const s: string): boolean;
@@ -679,36 +853,6 @@
     (AnsiStrLComp(PChar(s),PChar(UNKNOWN_VK_PREFIX),length(UNKNOWN_VK_PREFIX))=0);
 end;
 
-function KeyCodeToKeyString(Key: integer): string;
-begin
-  case Key of
-    VK_BACK:
-      Result := MenuKeyCaps[mkcBkSp];
-    VK_TAB:
-      Result := MenuKeyCaps[mkcTab];
-    VK_RETURN:
-      Result := MenuKeyCaps[mkcEnter];
-    VK_ESCAPE:
-      Result := MenuKeyCaps[mkcEsc];
-    VK_SPACE..VK_SPACE+8:
-      Result := MenuKeyCaps[TMenuKeyCap(Key - VK_SPACE + Ord(mkcSpace))];
-    VK_INSERT:
-      Result := MenuKeyCaps[mkcIns];
-    VK_DELETE:
-      Result := MenuKeyCaps[mkcDel];
-    VK_0..VK_9:
-      Result := Chr(Key - VK_0 + Ord('0'));
-    VK_A..VK_Z:
-      Result := Chr(Key - VK_A + Ord('A'));
-    VK_NUMPAD0..VK_NUMPAD9:
-      Result := 'Num' + Chr(Key - VK_NUMPAD0 + Ord('0')); // Delphi differs it from 0..9
-    VK_F1..VK_F24:
-      Result := 'F' + IntToStr(Key - (VK_F1-1));
-    else
-      Result := GetSpecialShortCutName(Key);
-  end;
-end;
-
 function ShortCutToText(ShortCut: TShortCut): string;
 var
   Name: string;
key2.diff (16,350 bytes)

CudaText man

2016-11-23 19:39

reporter  

key2fix.diff (17,046 bytes)
Index: lcl/lclproc.pas
===================================================================
--- lcl/lclproc.pas	(revision 53427)
+++ lcl/lclproc.pas	(working copy)
@@ -467,10 +467,278 @@
   MenuKeyCaps: array[TMenuKeyCap] of string;
   MenuKeyCapsInited: boolean = false;
 
+const
+  // MS documentation:
+  // https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
+  //
+  // Note: ShortcutToText must ignore single key Ctrl, Alt, Shift, Win,
+  // so these items have empty str here
+  //
+  KeyCodeStrings: array[1..$FF] of string = (
+    'Mouse_Left', // 0x1 - VK_LBUTTON
+    'Mouse_Right', // 0x2 - VK_RBUTTON
+    'Cancel', // 0x3 - VK_CANCEL - generated by Ctrl+Break
+    'Mouse_Middle', // 0x4 - VK_MBUTTON
+    'Mouse_X1', // 0x5 - VK_XBUTTON1
+    'Mouse_X2', // 0x6 - VK_XBUTTON2
+    '', // 0x7
+    'Backspace', // 0x8 - VK_BACK
+    'Tab', // 0x9 - VK_TAB
+    '', // 0xa
+    '', // 0xb
+    'NumClear', // 0xc - VK_CLEAR - generated by Num5 (NumLock off)
+    'Enter', // 0xd - VK_RETURN
+    '', // 0xe
+    '', // 0xf
+    '', //'Shift', // 0x10 - VK_SHIFT
+    '', //'Ctrl', // 0x11 - VK_CONTROL
+    '', //'Alt', // 0x12 - VK_MENU
+    'Break', // 0x13 - VK_PAUSE - Pause/Break key
+    'CapsLock', // 0x14 - VK_CAPITAL
+    'IME_Kana', // 0x15 - VK_KANA
+    '', // 0x16
+    'IME_Junja', // 0x17 - VK_JUNJA
+    'IME_final', // 0x18 - VK_FINAL
+    'IME_Hanja', // 0x19 - VK_HANJA
+    '', // 0x1a
+    'Esc', // 0x1b - VK_ESCAPE
+    'IME_convert', // 0x1c - VK_CONVERT
+    'IME_nonconvert', // 0x1d - VK_NONCONVERT
+    'IME_accept', // 0x1e - VK_ACCEPT
+    'IME_mode_change', // 0x1f - VK_MODECHANGE
+    'Space', // 0x20 - VK_SPACE
+    'PgUp', // 0x21 - VK_PRIOR
+    'PgDown', // 0x22 - VK_NEXT
+    'End', // 0x23 - VK_END
+    'Home', // 0x24 - VK_HOME
+    'Left', // 0x25 - VK_LEFT
+    'Up', // 0x26 - VK_UP
+    'Right', // 0x27 - VK_RIGHT
+    'Down', // 0x28 - VK_DOWN
+    'Select', // 0x29 - VK_SELECT
+    'Print', // 0x2a - VK_PRINT
+    'Execute', // 0x2b - VK_EXECUTE
+    'PrintScreen', // 0x2c - VK_SNAPSHOT
+    'Ins', // 0x2d - VK_INSERT
+    'Del', // 0x2e - VK_DELETE
+    'Help', // 0x2f - VK_HELP
+    '0', // 0x30
+    '1', // 0x31
+    '2', // 0x32
+    '3', // 0x33
+    '4', // 0x34
+    '5', // 0x35
+    '6', // 0x36
+    '7', // 0x37
+    '8', // 0x38
+    '9', // 0x39
+    '', // 0x3a
+    '', // 0x3b
+    '', // 0x3c
+    '', // 0x3d
+    '', // 0x3e
+    '', // 0x3f
+    '', // 0x40
+    'A', // 0x41
+    'B', // 0x42
+    'C', // 0x43
+    'D', // 0x44
+    'E', // 0x45
+    'F', // 0x46
+    'G', // 0x47
+    'H', // 0x48
+    'I', // 0x49
+    'J', // 0x4a
+    'K', // 0x4b
+    'L', // 0x4c
+    'M', // 0x4d
+    'N', // 0x4e
+    'O', // 0x4f
+    'P', // 0x50
+    'Q', // 0x51
+    'R', // 0x52
+    'S', // 0x53
+    'T', // 0x54
+    'U', // 0x55
+    'V', // 0x56
+    'W', // 0x57
+    'X', // 0x58
+    'Y', // 0x59
+    'Z', // 0x5a
+    '', //'LWindows', // 0x5b - VK_LWIN
+    '', //'RWindows', // 0x5c - VK_RWIN
+    'PopUp', // 0x5d - VK_APPS - PC, key near right Ctrl
+    '', // 0x5e
+    'Sleep', // 0x5f - VK_SLEEP
+    'Num0', // 0x60 - VK_NUMPAD0
+    'Num1', // 0x61
+    'Num2', // 0x62
+    'Num3', // 0x63
+    'Num4', // 0x64
+    'Num5', // 0x65
+    'Num6', // 0x66
+    'Num7', // 0x67
+    'Num8', // 0x68
+    'Num9', // 0x69 - VK_NUMPAD9
+    'NumMul', // 0x6a - VK_MULTIPLY
+    'NumPlus', // 0x6b - VK_ADD
+    'NumSepar', // 0x6c - VK_SEPARATOR
+    'NumMinus', // 0x6d - VK_SUBTRACT
+    'NumDot', // 0x6e - VK_DECIMAL
+    'NumDiv', // 0x6f - VK_DIVIDE
+    'F1', // 0x70 - VK_F1
+    'F2', // 0x71
+    'F3', // 0x72
+    'F4', // 0x73
+    'F5', // 0x74
+    'F6', // 0x75
+    'F7', // 0x76
+    'F8', // 0x77
+    'F9', // 0x78
+    'F10', // 0x79
+    'F11', // 0x7a
+    'F12', // 0x7b
+    'F13', // 0x7c
+    'F14', // 0x7d
+    'F15', // 0x7e
+    'F16', // 0x7f
+    'F17', // 0x80
+    'F18', // 0x81
+    'F19', // 0x82
+    'F20', // 0x83
+    'F21', // 0x84
+    'F22', // 0x85
+    'F23', // 0x86
+    'F24', // 0x87 - VK_F24
+    '', // 0x88
+    '', // 0x89
+    '', // 0x8a
+    '', // 0x8b
+    '', // 0x8c
+    '', // 0x8d
+    '', // 0x8e
+    '', // 0x8f
+    'NumLock', // 0x90 - VK_NUMLOCK
+    'ScrollLock', // 0x91 - VK_SCROLL
+    'OEM_0x92', // 0x92
+    'OEM_0x93', // 0x93
+    'OEM_0x94', // 0x94
+    'OEM_0x95', // 0x95
+    'OEM_0x96', // 0x96
+    '', // 0x97
+    '', // 0x98
+    '', // 0x99
+    '', // 0x9a
+    '', // 0x9b
+    '', // 0x9c
+    '', // 0x9d
+    '', // 0x9e
+    '', // 0x9f
+    '', //'LShift', // 0xa0 - VK_LSHIFT
+    '', //'RShift', // 0xa1 - VK_RSHIFT
+    '', //'LCtrl', // 0xa2 - VK_LCONTROL
+    '', //'RCtrl', // 0xa3 - VK_RCONTROL
+    '', //'LAlt', // 0xa4 - VK_LMENU
+    '', //'RAlt', // 0xa5 - VK_RMENU
+    'BrowserBack', // 0xa6 - VK_BROWSER_BACK
+    'BrowserForward', // 0xa7 - VK_BROWSER_FORWARD
+    'BrowserRefresh', // 0xa8 - VK_BROWSER_REFRESH
+    'BrowserStop', // 0xa9 - VK_BROWSER_STOP
+    'BrowserSearch', // 0xaa - VK_BROWSER_SEARCH
+    'BrowserFav', // 0xab - VK_BROWSER_FAVORITES
+    'BrowserHome', // 0xac - VK_BROWSER_HOME
+    'VolumeMute', // 0xad - VK_VOLUME_MUTE
+    'VolumeDown', // 0xae - VK_VOLUME_DOWN
+    'VolumeUp', // 0xaf - VK_VOLUME_UP
+    'MediaNext', // 0xb0 - VK_MEDIA_NEXT_TRACK
+    'MediaPrev', // 0xb1 - VK_MEDIA_PREV_TRACK
+    'MediaStop', // 0xb2 - VK_MEDIA_STOP
+    'MediaPlayPause', // 0xb3 - VK_MEDIA_PLAY_PAUSE
+    'LaunchMail', // 0xb4 - VK_LAUNCH_MAIL
+    'LaunchMedia', // 0xb5 - VK_LAUNCH_MEDIA_SELECT
+    'LaunchApp1', // 0xb6 - VK_LAUNCH_APP1
+    'LaunchApp2', // 0xb7 - VK_LAUNCH_APP2
+    '', // 0xb8
+    '', // 0xb9
+    ';', // 0xba - VK_OEM_1 - Can vary by keyboard, US keyboard, the ';:' key
+    '+', // 0xbb - VK_OEM_PLUS - For any country/region, the '+' key
+    ',', // 0xbc - VK_OEM_COMMA - For any country/region, the ',' key
+    '-', // 0xbd - VK_OEM_MINUS - For any country/region, the '-' key
+    '.', // 0xbe - VK_OEM_PERIOD - For any country/region, the '.' key
+    '/', // 0xbf - VK_OEM_2 - Can vary by keyboard, US keyboard, the '/?' key
+    '`', // 0xc0 - VK_OEM_3 - Can vary by keyboard, US keyboard, the '`~' key
+    '', // 0xc1
+    '', // 0xc2
+    '', // 0xc3
+    '', // 0xc4
+    '', // 0xc5
+    '', // 0xc6
+    '', // 0xc7
+    '', // 0xc8
+    '', // 0xc9
+    '', // 0xca
+    '', // 0xcb
+    '', // 0xcc
+    '', // 0xcd
+    '', // 0xce
+    '', // 0xcf
+    '', // 0xd0
+    '', // 0xd1
+    '', // 0xd2
+    '', // 0xd3
+    '', // 0xd4
+    '', // 0xd5
+    '', // 0xd6
+    '', // 0xd7
+    '', // 0xd8
+    '', // 0xd9
+    '', // 0xda
+    '[', // 0xdb - VK_OEM_4 - Can vary by keyboard, US keyboard, the '[{' key
+    '\', // 0xdc - VK_OEM_5 - Can vary by keyboard, US keyboard, the '\|' key
+    ']', // 0xdd - VK_OEM_6 - Can vary by keyboard, US keyboard, the ']}' key
+    '''', // 0xde - VK_OEM_7 - Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
+    'OEM_8', // 0xdf - VK_OEM_8
+    '', // 0xe0
+    'OEM_0xE1', // 0xe1
+    '\', // 0xe2 - VK_OEM_102 - Either the angle bracket key or the backslash key on the RT 102-key keyboard
+    'OEM_0xE3', // 0xe3
+    'OEM_0xE4', // 0xe4
+    'IME_process', // 0xe5 - VK_PROCESSKEY
+    'OEM_0xE6', // 0xe6
+    'UnicodePacket', // 0xe7 - VK_PACKET
+    '', // 0xe8
+    'OEM_0xE9', // 0xe9
+    'OEM_0xEA', // 0xea
+    'OEM_0xEB', // 0xeb
+    'OEM_0xEC', // 0xec
+    'OEM_0xED', // 0xed
+    'OEM_0xEE', // 0xee
+    'OEM_0xEF', // 0xef
+    'OEM_0xF0', // 0xf0
+    'OEM_0xF1', // 0xf1
+    'OEM_0xF2', // 0xf2
+    'OEM_0xF3', // 0xf3
+    'OEM_0xF4', // 0xf4
+    'OEM_0xF5', // 0xf5
+    'Attn', // 0xf6 - VK_ATTN
+    'CrSel', // 0xf7 - VK_CRSEL
+    'ExSel', // 0xf8 - VK_EXSEL
+    'EraseEOF', // 0xf9 - VK_EREOF
+    'Play', // 0xfa - VK_PLAY
+    'Zoom', // 0xfb - VK_ZOOM
+    '', // 0xfc
+    'PA1', // 0xfd - VK_PA1
+    'OEM_Clear', // 0xfe - VK_OEM_CLEAR
+    '' // 0xff
+  );
+
+
 procedure InitializeMenuKeyCaps;
 begin
-  if MenuKeyCapsInited=false then
+  if not MenuKeyCapsInited then
   begin
+    MenuKeyCapsInited:=true;
+
     MenuKeyCaps[mkcBkSp]:=SmkcBkSp;
     MenuKeyCaps[mkcTab]:=SmkcTab;
     MenuKeyCaps[mkcEsc]:=SmkcEsc;
@@ -490,58 +758,26 @@
     MenuKeyCaps[mkcCtrl]:=SmkcCtrl;
     MenuKeyCaps[mkcAlt]:=SmkcAlt;
     MenuKeyCaps[mkcMeta]:=SmkcMeta;
-    MenuKeyCapsInited:=true;
-  end;
-end;
 
-function GetSpecialShortCutName(Key: integer): string;
-begin
-  Result := '';
-  case Key of
-    VK_CANCEL:     Result := 'Cancel'; //generated by Ctrl+Break
-    VK_CLEAR:      Result := 'NumClear'; //generated by Num5 (NumLock off)
-    VK_PAUSE:      Result := 'Break';
-    VK_CAPITAL:    Result := 'CapsLock';
-    VK_APPS:       Result := 'PopUp'; //PC, near right Ctrl
-    VK_MULTIPLY:   Result := 'NumMul';
-    VK_ADD:        Result := 'NumPlus';
-    VK_SUBTRACT:   Result := 'NumMinus';
-    VK_DECIMAL:    Result := 'NumDot';
-    VK_DIVIDE:     Result := 'NumDiv';
-    VK_NUMLOCK:    Result := 'NumLock';
-    VK_SCROLL:     Result := 'ScrollLock';
-    VK_OEM_1:      Result := ';'; // Can vary by keyboard, US keyboard, the ';:' key
-    VK_OEM_PLUS:   Result := '+'; // For any country/region, the '+' key
-    VK_OEM_COMMA:  Result := ','; // For any country/region, the ',' key
-    VK_OEM_MINUS:  Result := '-'; // For any country/region, the '-' key
-    VK_OEM_PERIOD: Result := '.'; // For any country/region, the '.' key
-    VK_OEM_2:      Result := '/'; // Can vary by keyboard, US keyboard, the '/?' key
-    VK_OEM_3:      Result := '`'; // Can vary by keyboard, US keyboard, the '`~' key
-    VK_OEM_4:      Result := '['; // Can vary by keyboard, US keyboard, the '[{' key
-    VK_OEM_5:      Result := '\'; // Can vary by keyboard, US keyboard, the '\|' key
-    VK_OEM_6:      Result := ']'; // Can vary by keyboard, US keyboard, the ']}' key
-    VK_OEM_7:      Result := ''''; // Can vary by keyboard, US keyboard, the 'single-quote/double-quote' key
-    VK_OEM_102:    Result := '\'; // Either the angle bracket key or the backslash key on the RT 102-key keyboard
-
-    //Windows keyboard special:
-    $A6: Result := 'BrowserBack';
-    $A7: Result := 'BrowserForward';
-    $A8: Result := 'BrowserRefresh';
-    $A9: Result := 'BrowserStop';
-    $AA: Result := 'BrowserSearch';
-    $AB: Result := 'BrowserFav';
-    $AC: Result := 'BrowserHome';
-    $AD: Result := 'VolumeMute';
-    $AE: Result := 'VolumeDown';
-    $AF: Result := 'VolumeUp';
-    $B0: Result := 'MediaNext';
-    $B1: Result := 'MediaPrev';
-    $B2: Result := 'MediaStop';
-    $B3: Result := 'MediaPlay';
-    $B4: Result := 'LaunchMail';
-    $B5: Result := 'LaunchMedia';
-    $B6: Result := 'LaunchApp1';
-    $B7: Result := 'LaunchApp2';
+    KeyCodeStrings[VK_BACK]:=SmkcBkSp;
+    KeyCodeStrings[VK_TAB]:=SmkcTab;
+    KeyCodeStrings[VK_ESCAPE]:=SmkcEsc;
+    KeyCodeStrings[VK_RETURN]:=SmkcEnter;
+    KeyCodeStrings[VK_SPACE]:=SmkcSpace;
+    KeyCodeStrings[VK_PRIOR]:=SmkcPgUp;
+    KeyCodeStrings[VK_NEXT]:=SmkcPgDn;
+    KeyCodeStrings[VK_END]:=SmkcEnd;
+    KeyCodeStrings[VK_HOME]:=SmkcHome;
+    KeyCodeStrings[VK_LEFT]:=SmkcLeft;
+    KeyCodeStrings[VK_UP]:=SmkcUp;
+    KeyCodeStrings[VK_RIGHT]:=SmkcRight;
+    KeyCodeStrings[VK_DOWN]:=SmkcDown;
+    KeyCodeStrings[VK_INSERT]:=SmkcIns;
+    KeyCodeStrings[VK_DELETE]:=SmkcDel;
+    // must ignore single Shift, Alt, Ctrl in KeyCodeStrings
+    //KeyCodeStrings[VK_SHIFT]:=SmkcShift;
+    //KeyCodeStrings[VK_CONTROL]:=SmkcCtrl;
+    //KeyCodeStrings[VK_MENU]:=SmkcAlt;
   end;
 end;
 
@@ -575,6 +811,14 @@
     Result:=DefaultValue;
 end;
 
+function KeyCodeToKeyString(Key: integer): string;
+begin
+  if (Key>=Low(KeyCodeStrings)) and (Key<=High(KeyCodeStrings)) then
+    Result := KeyCodeStrings[Key]
+  else
+    Result := '';
+end;
+
 // Used also by TWidgetSet.GetAcceleratorString
 function KeyAndShiftStateToKeyString(Key: word; ShiftState: TShiftState): String;
 
@@ -585,79 +829,8 @@
     Result := Result + APart;
   end;
 
-  // Tricky routine. This only works for western languages
-  procedure AddKey;
-  begin
-    case Key of
-      VK_UNKNOWN    :AddPart(ifsVK_UNKNOWN);
-      VK_LBUTTON    :AddPart(ifsVK_LBUTTON);
-      VK_RBUTTON    :AddPart(ifsVK_RBUTTON);
-      VK_CANCEL     :AddPart(ifsVK_CANCEL);
-      VK_MBUTTON    :AddPart(ifsVK_MBUTTON);
-      VK_BACK       :AddPart(ifsVK_BACK);
-      VK_TAB        :AddPart(ifsVK_TAB);
-      VK_CLEAR      :AddPart(ifsVK_CLEAR);
-      VK_RETURN     :AddPart(ifsVK_RETURN);
-      VK_SHIFT      :AddPart(ifsVK_SHIFT);
-      VK_CONTROL    :AddPart(ifsVK_CONTROL);
-      VK_MENU       :AddPart(ifsVK_MENU);
-      VK_PAUSE      :AddPart(ifsVK_PAUSE);
-      VK_CAPITAL    :AddPart(ifsVK_CAPITAL);
-      VK_KANA       :AddPart(ifsVK_KANA);
-    //  VK_HANGUL     :AddPart('Hangul');
-      VK_JUNJA      :AddPart(ifsVK_JUNJA);
-      VK_FINAL      :AddPart(ifsVK_FINAL);
-      VK_HANJA      :AddPart(ifsVK_HANJA );
-    //  VK_KANJI      :AddPart('Kanji');
-      VK_ESCAPE     :AddPart(ifsVK_ESCAPE);
-      VK_CONVERT    :AddPart(ifsVK_CONVERT);
-      VK_NONCONVERT :AddPart(ifsVK_NONCONVERT);
-      VK_ACCEPT     :AddPart(ifsVK_ACCEPT);
-      VK_MODECHANGE :AddPart(ifsVK_MODECHANGE);
-      VK_SPACE      :AddPart(ifsVK_SPACE);
-      VK_PRIOR      :AddPart(ifsVK_PRIOR);
-      VK_NEXT       :AddPart(ifsVK_NEXT);
-      VK_END        :AddPart(ifsVK_END);
-      VK_HOME       :AddPart(ifsVK_HOME);
-      VK_LEFT       :AddPart(ifsVK_LEFT);
-      VK_UP         :AddPart(ifsVK_UP);
-      VK_RIGHT      :AddPart(ifsVK_RIGHT);
-      VK_DOWN       :AddPart(ifsVK_DOWN);
-      VK_SELECT     :AddPart(ifsVK_SELECT);
-      VK_PRINT      :AddPart(ifsVK_PRINT);
-      VK_EXECUTE    :AddPart(ifsVK_EXECUTE);
-      VK_SNAPSHOT   :AddPart(ifsVK_SNAPSHOT);
-      VK_INSERT     :AddPart(ifsVK_INSERT);
-      VK_DELETE     :AddPart(ifsVK_DELETE);
-      VK_HELP       :AddPart(ifsVK_HELP);
-      VK_0..VK_9    :AddPart(chr(ord('0')+Key-VK_0));
-      VK_A..VK_Z    :AddPart(chr(ord('A')+Key-VK_A));
-      VK_LWIN       :AddPart(ifsVK_LWIN);
-      VK_RWIN       :AddPart(ifsVK_RWIN);
-      VK_APPS       :AddPart(ifsVK_APPS);
-      VK_NUMPAD0..VK_NUMPAD9:  AddPart(Format(ifsVK_NUMPAD,[Key-VK_NUMPAD0]));
-      VK_MULTIPLY   :AddPart('*');
-      VK_ADD        :AddPart('+');
-      VK_OEM_PLUS   :AddPart('+');
-      VK_SEPARATOR  :AddPart('|');
-      VK_SUBTRACT   :AddPart('-');
-      VK_OEM_MINUS  :AddPart('-');
-      VK_DECIMAL    :AddPart('.');
-      VK_OEM_PERIOD :AddPart('.');
-      VK_OEM_COMMA  :AddPart(',');
-      VK_DIVIDE     :AddPart('/');
-      VK_F1..VK_F24: AddPart('F'+IntToStr(Key-VK_F1+1));
-      VK_NUMLOCK    :AddPart(ifsVK_NUMLOCK);
-      VK_SCROLL     :AddPart(ifsVK_SCROLL);
-      VK_OEM_2      :AddPart('OEM2');
-      VK_OEM_3      :AddPart('OEM3');
-//    VK_EQUAL      :AddPart('=');
-//    VK_AT         :AddPart('@');
-    else
-      AddPart(UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX);
-    end;
-  end;
-
+var
+  S: string;
 begin
   Result := '';
   if ssCtrl in ShiftState then AddPart(ifsCtrl);
@@ -670,7 +843,12 @@
     AddPart(ifsVK_META);
     {$ENDIF}
   if ssSuper in ShiftState then AddPart(ifsVK_SUPER);
-  AddKey;
+
+  S := KeyCodeToKeyString(Key);
+  // function returned "Word(nnn)" previously, keep this
+  if S='' then
+    S := UNKNOWN_VK_PREFIX + IntToStr(Key) + UNKNOWN_VK_POSTFIX;
+  AddPart(S);
 end;
 
 function KeyStringIsIrregular(const s: string): boolean;
@@ -679,36 +857,6 @@
     (AnsiStrLComp(PChar(s),PChar(UNKNOWN_VK_PREFIX),length(UNKNOWN_VK_PREFIX))=0);
 end;
 
-function KeyCodeToKeyString(Key: integer): string;
-begin
-  case Key of
-    VK_BACK:
-      Result := MenuKeyCaps[mkcBkSp];
-    VK_TAB:
-      Result := MenuKeyCaps[mkcTab];
-    VK_RETURN:
-      Result := MenuKeyCaps[mkcEnter];
-    VK_ESCAPE:
-      Result := MenuKeyCaps[mkcEsc];
-    VK_SPACE..VK_SPACE+8:
-      Result := MenuKeyCaps[TMenuKeyCap(Key - VK_SPACE + Ord(mkcSpace))];
-    VK_INSERT:
-      Result := MenuKeyCaps[mkcIns];
-    VK_DELETE:
-      Result := MenuKeyCaps[mkcDel];
-    VK_0..VK_9:
-      Result := Chr(Key - VK_0 + Ord('0'));
-    VK_A..VK_Z:
-      Result := Chr(Key - VK_A + Ord('A'));
-    VK_NUMPAD0..VK_NUMPAD9:
-      Result := 'Num' + Chr(Key - VK_NUMPAD0 + Ord('0')); // Delphi differs it from 0..9
-    VK_F1..VK_F24:
-      Result := 'F' + IntToStr(Key - (VK_F1-1));
-    else
-      Result := GetSpecialShortCutName(Key);
-  end;
-end;
-
 function ShortCutToText(ShortCut: TShortCut): string;
 var
   Name: string;
@@ -765,8 +913,10 @@
     else
       Break;
   end;
-  for Key := $08 to $FF do begin { Copy range from table in ShortCutToText }
-    Name := ShortCutToText(Key);
+
+  for Key := Low(KeyCodeStrings) to High(KeyCodeStrings) do
+  begin
+    Name := KeyCodeToKeyString(Key);
     if (Name<>'') and (length(Name)=length(ShortCutText)-StartPos+1)
     and (AnsiStrLIComp(@ShortCutText[StartPos], PChar(Name), length(Name)) = 0)
     then begin
key2fix.diff (17,046 bytes)

CudaText man

2016-11-23 19:40

reporter   ~0096170

Update (fix for single key press of Ctrl/ Alt/ Shift/ Win)

Michl

2016-11-23 20:44

developer   ~0096173

Just as a note. If you really want to redesign the code of ShortCutToText and its used methods, it would be good to be Delphi compatible. Delphi translate a key value to the locale. So a array of string isn't a real good choice. IMHO, better would be to define the undefined keys in LCLStrConsts as ResourceString and take that one. The most of them are already defined there:

...
  ifsVK_BACK = 'Backspace';
  ifsVK_TAB = 'Tab';
  ifsVK_CLEAR = 'Clear';
  ifsVK_RETURN = 'Return';
  ifsVK_SHIFT = 'Shift';
     
and so on

CudaText man

2016-11-23 21:01

reporter   ~0096174

Last edited: 2016-11-23 21:04

View 3 revisions

Michl,
not right, I already use Laz resource strings here

procedure InitializeMenuKeyCaps;
..
    KeyCodeStrings[VK_BACK]:=SmkcBkSp;
    KeyCodeStrings[VK_TAB]:=SmkcTab;
    KeyCodeStrings[VK_ESCAPE]:=SmkcEsc;
    KeyCodeStrings[VK_RETURN]:=SmkcEnter;
    KeyCodeStrings[VK_SPACE]:=SmkcSpace;
    KeyCodeStrings[VK_PRIOR]:=SmkcPgUp;
    KeyCodeStrings[VK_NEXT]:=SmkcPgDn;
    KeyCodeStrings[VK_END]:=SmkcEnd;
    KeyCodeStrings[VK_HOME]:=SmkcHome;
    KeyCodeStrings[VK_LEFT]:=SmkcLeft;
    KeyCodeStrings[VK_UP]:=SmkcUp;
    KeyCodeStrings[VK_RIGHT]:=SmkcRight;
    KeyCodeStrings[VK_DOWN]:=SmkcDown;
    KeyCodeStrings[VK_INSERT]:=SmkcIns;
    KeyCodeStrings[VK_DELETE]:=SmkcDel;
    // must ignore single Shift, Alt, Ctrl in KeyCodeStrings
    //KeyCodeStrings[VK_SHIFT]:=SmkcShift;
    //KeyCodeStrings[VK_CONTROL]:=SmkcCtrl;
    //KeyCodeStrings[VK_MENU]:=SmkcAlt;

No problem to add here using of OS locale strings

Michl

2016-11-24 10:13

developer   ~0096189

Last edited: 2016-11-24 10:15

View 4 revisions

> Michl, not right, I already use Laz resource strings here

Ah, yes you are right, you replace your KeyCodeStrings array with the values from LCLStrConsts.

I personally like the idea to simplify code and use one method for mostly the same things.

Whatever, I have some hints:

You changed the used resourcestring constansts e.g. ifsVK_PRIOR to SmkcPgUp so e.g. at German locale, some keys strings aren't translated anymore: MainMenu -> IDE Options -> Key mappings -> Cursor moving commands -> Move cursor up one page.
Maybe it is better to use the ifsVK_... constants instead of the Smkc... constants, which are used before in KeyAndShiftStateToKeyString.AddKey?

I also see, not all the strings in KeyCodeStrings are replaced, which are used before in LCLProc.KeyAndShiftStateToKeyString.AddKey. I don't know, if that breaks existing behaviour somewhere (e.g. VK_JUNJA, VK_FINAL, VK_HANJA and so on).

To use a array, filled one time, could be nice idea, to get the real available keyboard keys and to use them. So a (slow) native keyscan is only one time needed.
I don't know (not tested), if InitializeMenuKeyCaps is called, if the current locale is changed on runtime, so the KeyCodeStrings are replaced with the current locale strings?

CudaText man

2016-11-24 14:17

reporter   ~0096196

>Maybe it is better to use the ifsVK_... constants instead of the Smkc... constants, which are used before

I donot think that ifsVK consts are better. See-
 ifsVK_RETURN = 'Return'; is not good str here, "Enter" is ok, "Return" not
  ifsVK_CONTROL = 'Control'; is not good std, "Ctrl" is ok/better
   ifsVK_MENU = 'Menu'; is not good, "Alt" is better
 ifsVK_CAPITAL = 'Capital'; is not good, since "CapsLock" better
  ifsVK_KANA = 'Kana'; is not good, i made other strings "IME_nnnnnn" e.g. "IME_Kana"
  "IME" prefix is good/handy
 ifsVK_ESCAPE = 'Escape'; is not good, "Esc" better
  ifsVK_SPACE = 'Space key'; is not good, "Space" simpler+better
 ifsVK_PRIOR = 'Prior'; is not good, "PgUp/PgDn" are usual names
        
so, ShortcutToText will give ugly values


>not all the strings in KeyCodeStrings are replaced
IMO no need to replace all
(it is only to show in Ui)

Bart Broersma

2016-11-26 19:45

developer   ~0096271

Note: localizing VK_xxx codes IMO is a PITA.
My keyborad does not have a key that says "eind", it clearly says "end", nevertheless the shortcut text insist on "eind" in the menu item.

Michl

2016-11-26 20:06

developer   ~0096272

> Note: localizing VK_xxx codes IMO is a PITA.

Why? It is more the five years in the LCL. On german keyboards the keys have german names. In front of me, my keyboard shows for "End" a "Ende". See https://upload.wikimedia.org/wikipedia/commons/b/b0/German-T2-Keyboard-Prototype-May-2012.jpg

CudaText man

2016-11-26 20:11

reporter   ~0096273

My pch localizes, via Laz constants, as less as it can

Juha Manninen

2018-02-20 20:41

developer   ~0106491

Michl, please decide what to do with the patch. Apply or reject. If it works ok then I guess it should be applied. I am not sure why it is needed though. Speedwise it makes no big difference, the compiler optimizes case clauses well.

CudaText man

2018-02-20 21:28

reporter   ~0106493

Only misfeature of this patch: is some change in i18n. mentioned in comments.
Im sure it can be fixed.

Michl

2018-02-21 20:15

developer   ~0106521

> Only misfeature of this patch: is some change in i18n. mentioned in comments.
> Im sure it can be fixed.

Yes, this was the show stopper. I don't wanted apply something that breaks backward compatibility.

> please decide what to do with the patch.
You are right. I'll have a look at it at sunday.

Michl

2018-02-25 15:14

developer  

test.zip (558 bytes)

Michl

2018-02-25 15:45

developer   ~0106618

I applied the patch, as IMHO the advantages overweight the disadvantages. The localization can of course be fixed by editing the .po files.

Thank you

CudaText man

2018-07-07 07:08

reporter   ~0109253

@Michl and others,
let's discuss i18n issues here:
http://forum.lazarus.freepascal.org/index.php/topic,41664.0.html

Issue History

Date Modified Username Field Change
2016-11-23 18:19 CudaText man New Issue
2016-11-23 18:19 CudaText man File Added: key2.diff
2016-11-23 19:39 CudaText man File Added: key2fix.diff
2016-11-23 19:40 CudaText man Note Added: 0096170
2016-11-23 20:44 Michl Note Added: 0096173
2016-11-23 20:45 Michl Relationship added related to 0030988
2016-11-23 20:45 Michl Relationship added related to 0030973
2016-11-23 21:01 CudaText man Note Added: 0096174
2016-11-23 21:02 CudaText man Note Edited: 0096174 View Revisions
2016-11-23 21:04 CudaText man Note Edited: 0096174 View Revisions
2016-11-24 10:13 Michl Note Added: 0096189
2016-11-24 10:14 Michl Note Edited: 0096189 View Revisions
2016-11-24 10:14 Michl Note Edited: 0096189 View Revisions
2016-11-24 10:15 Michl Note Edited: 0096189 View Revisions
2016-11-24 14:17 CudaText man Note Added: 0096196
2016-11-26 19:45 Bart Broersma Note Added: 0096271
2016-11-26 20:06 Michl Note Added: 0096272
2016-11-26 20:11 CudaText man Note Added: 0096273
2016-12-10 13:14 Michl Note View State: 0096272: public
2016-12-10 13:38 Michl Assigned To => Michl
2016-12-10 13:38 Michl Status new => assigned
2017-08-21 13:11 Michl Relationship added related to 0023082
2018-02-20 20:41 Juha Manninen Note Added: 0106491
2018-02-20 21:28 CudaText man Note Added: 0106493
2018-02-21 20:15 Michl Note Added: 0106521
2018-02-25 15:14 Michl File Added: test.zip
2018-02-25 15:45 Michl Fixed in Revision => 57373
2018-02-25 15:45 Michl LazTarget => -
2018-02-25 15:45 Michl Note Added: 0106618
2018-02-25 15:45 Michl Status assigned => resolved
2018-02-25 15:45 Michl Resolution open => fixed
2018-07-07 07:08 CudaText man Note Added: 0109253
2018-07-28 21:56 Michl Relationship added related to 0034045