You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
6.2 KiB

  1. unit uutlKeyCodes;
  2. { Package: Utils
  3. Prefix: utl - UTiLs
  4. Beschreibung: diese Unit enthält alle virtuellen Key Codes }
  5. {$mode objfpc}{$H+}
  6. interface
  7. uses Classes;
  8. {$REGION SCANCODES}
  9. const
  10. VK_UNKNOWN = 0; // defined by LCL
  11. VK_LBUTTON = 1;
  12. VK_RBUTTON = 2;
  13. VK_CANCEL = 3;
  14. VK_MBUTTON = 4;
  15. VK_XBUTTON1 = 5;
  16. VK_XBUTTON2 = 6;
  17. VK_BACK = 8; // The "Backspace" key, dont confuse with the
  18. // Android BACK key which is mapped to VK_ESCAPE
  19. VK_TAB = 9;
  20. VK_CLEAR = 12;
  21. VK_RETURN = 13; // The "Enter" key, also used for a keypad center press
  22. VK_SHIFT = 16; // See also VK_LSHIFT, VK_RSHIFT
  23. VK_CONTROL = 17; // See also VK_LCONTROL, VK_RCONTROL
  24. VK_MENU = 18;
  25. // The ALT key. Also called "Option" in Mac OS X. See also VK_LMENU, VK_RMENU
  26. VK_PAUSE = 19; // Pause/Break key
  27. VK_CAPITAL = 20; // CapsLock key
  28. VK_KANA = 21;
  29. VK_HANGUL = 21;
  30. VK_JUNJA = 23;
  31. VK_FINAL = 24;
  32. VK_HANJA = 25;
  33. VK_KANJI = 25;
  34. VK_ESCAPE = 27; // Also used for the hardware Back key in Android
  35. VK_CONVERT = 28;
  36. VK_NONCONVERT = 29;
  37. VK_ACCEPT = 30;
  38. VK_MODECHANGE = 31;
  39. VK_SPACE = 32;
  40. VK_PRIOR = 33; // Page Up
  41. VK_NEXT = 34; // Page Down
  42. VK_END = 35;
  43. VK_HOME = 36;
  44. VK_LEFT = 37;
  45. VK_UP = 38;
  46. VK_RIGHT = 39;
  47. VK_DOWN = 40;
  48. VK_SELECT = 41;
  49. VK_PRINT = 42; // PrintScreen key
  50. VK_EXECUTE = 43;
  51. VK_SNAPSHOT = 44;
  52. VK_INSERT = 45;
  53. VK_DELETE = 46;
  54. VK_HELP = 47;
  55. VK_0 = $30;
  56. VK_1 = $31;
  57. VK_2 = $32;
  58. VK_3 = $33;
  59. VK_4 = $34;
  60. VK_5 = $35;
  61. VK_6 = $36;
  62. VK_7 = $37;
  63. VK_8 = $38;
  64. VK_9 = $39;
  65. //3A-40 Undefined
  66. VK_A = $41;
  67. VK_B = $42;
  68. VK_C = $43;
  69. VK_D = $44;
  70. VK_E = $45;
  71. VK_F = $46;
  72. VK_G = $47;
  73. VK_H = $48;
  74. VK_I = $49;
  75. VK_J = $4A;
  76. VK_K = $4B;
  77. VK_L = $4C;
  78. VK_M = $4D;
  79. VK_N = $4E;
  80. VK_O = $4F;
  81. VK_P = $50;
  82. VK_Q = $51;
  83. VK_R = $52;
  84. VK_S = $53;
  85. VK_T = $54;
  86. VK_U = $55;
  87. VK_V = $56;
  88. VK_W = $57;
  89. VK_X = $58;
  90. VK_Y = $59;
  91. VK_Z = $5A;
  92. VK_LWIN = $5B;
  93. // In Mac OS X this is the Apple, or Command key. Windows Key in PC keyboards
  94. VK_RWIN = $5C;
  95. // In Mac OS X this is the Apple, or Command key. Windows Key in PC keyboards
  96. VK_APPS = $5D; // The PopUp key in PC keyboards
  97. // $5E reserved
  98. VK_SLEEP = $5F;
  99. VK_NUMPAD0 = 96; // $60
  100. VK_NUMPAD1 = 97;
  101. VK_NUMPAD2 = 98;
  102. VK_NUMPAD3 = 99;
  103. VK_NUMPAD4 = 100;
  104. VK_NUMPAD5 = 101;
  105. VK_NUMPAD6 = 102;
  106. VK_NUMPAD7 = 103;
  107. VK_NUMPAD8 = 104;
  108. VK_NUMPAD9 = 105;
  109. VK_MULTIPLY = 106;
  110. // VK_MULTIPLY up to VK_DIVIDE are usually in the numeric keypad in PC keyboards
  111. VK_ADD = 107;
  112. VK_SEPARATOR = 108;
  113. VK_SUBTRACT = 109;
  114. VK_DECIMAL = 110;
  115. VK_DIVIDE = 111;
  116. VK_F1 = 112;
  117. VK_F2 = 113;
  118. VK_F3 = 114;
  119. VK_F4 = 115;
  120. VK_F5 = 116;
  121. VK_F6 = 117;
  122. VK_F7 = 118;
  123. VK_F8 = 119;
  124. VK_F9 = 120;
  125. VK_F10 = 121;
  126. VK_F11 = 122;
  127. VK_F12 = 123;
  128. VK_F13 = 124;
  129. VK_F14 = 125;
  130. VK_F15 = 126;
  131. VK_F16 = 127;
  132. VK_F17 = 128;
  133. VK_F18 = 129;
  134. VK_F19 = 130;
  135. VK_F20 = 131;
  136. VK_F21 = 132;
  137. VK_F22 = 133;
  138. VK_F23 = 134;
  139. VK_F24 = 135; // $87
  140. // $88-$8F unassigned
  141. VK_NUMLOCK = $90;
  142. VK_SCROLL = $91;
  143. {$ENDREGION}
  144. function CharCodeToVKCode(Ch: WideChar; out shift: TShiftState): word;
  145. function VKCodeToCharCode(key: word; Shift: TShiftState): WideChar;
  146. implementation
  147. {$IFDEF WINDOWS}
  148. uses Windows;
  149. function CharCodeToVKCode(Ch: WideChar; out shift: TShiftState): word;
  150. var
  151. st: SmallInt;
  152. begin
  153. shift:= [];
  154. Result:= 0;
  155. if ch=#0 then
  156. exit;
  157. st:= VkKeyScan(AnsiChar(UnicodeChar(ch)));
  158. if (hi(st)=$FF) and (lo(st)=$FF) then
  159. exit;
  160. Result:= lo(st);
  161. if Result and (1 shl 8) > 0 then include(shift, ssShift);
  162. if Result and (2 shl 8) > 0 then include(shift, ssCtrl);
  163. if Result and (4 shl 8) > 0 then include(shift, ssAlt);
  164. if [ssCtrl, ssAlt] - shift = [] then
  165. include(shift, ssAltGr);
  166. end;
  167. function VKCodeToCharCode(key: word; Shift: TShiftState): WideChar;
  168. var
  169. sc: word;
  170. ks: array[0..255] of byte;
  171. buf: array[0..1] of AnsiChar;
  172. begin
  173. Result:= #0;
  174. sc:= MapVirtualKey(key, {MAPVK_VK_TO_VSC} 0);
  175. FillChar({%H-}ks[0], sizeof(ks), 0);
  176. if ssShift in Shift then ks[VK_SHIFT]:= $80;
  177. if ssCtrl in Shift then ks[VK_CONTROL]:= $80;
  178. if ssAlt in Shift then ks[VK_MENU]:= $80;
  179. if ssCaps in Shift then ks[VK_CAPITAL]:= $81;
  180. buf:= #0#0;
  181. case ToAscii(key, sc, @ks[0], LPWORD(@buf[0]), 0) of
  182. 0: Result:= #0;//The specified virtual key has no translation for the current state of the keyboard.
  183. 1: Result:= UnicodeChar(AnsiChar(buf[0]));//One character was copied to the buffer
  184. 2: Result:= UnicodeChar(AnsiChar(buf[1]));//Two characters were copied to the buffer. This usually happens when a dead-key character (accent or diacritic) stored in the keyboard layout cannot be composed with the specified virtual key to form a single character.
  185. end;
  186. end;
  187. {$ELSE}
  188. uses SysUtils, gtk2proc;
  189. function VKCodeToCharCode(key: word; Shift: TShiftState): WideChar;
  190. var
  191. vki: TVKeyInfo;
  192. dt: PAnsiChar;
  193. begin
  194. Result:= #0;
  195. vki:= GetVKeyInfo(Key);
  196. if strlen(vki.KeyChar[0])>0 then begin
  197. dt:= '';
  198. if []=Shift then
  199. dt:= vki.KeyChar[0]
  200. else
  201. if ([ssShift]=Shift) or ([ssCaps]=Shift) then
  202. dt:= vki.KeyChar[1]
  203. else
  204. if ([ssCtrl, ssAlt]=Shift) or ([ssAltGr]=Shift) then
  205. dt:= vki.KeyChar[2];
  206. Utf8ToUnicode(@Result, 1, PChar(dt), strlen(dt));
  207. end;
  208. end;
  209. function CharCodeToVKCode(Ch: WideChar; out shift: TShiftState): word;
  210. var
  211. k: Word;
  212. vki: TVKeyInfo;
  213. utf8ch: array[0..high(TVKeyUTF8Char)] of AnsiChar;
  214. begin
  215. Result:= 0;
  216. if ch=#0 then
  217. exit;
  218. utf8ch:= #0#0#0#0#0#0#0#0; //wat
  219. UnicodeToUTF8(@utf8ch[0], sizeof(utf8ch), @ch, 1);
  220. for k:= low(byte) to high(byte) do begin
  221. vki:= GetVKeyInfo(k);
  222. if CompareMem(@utf8ch, @vki.KeyChar[0], sizeof(utf8ch)) then begin
  223. Result:= k;
  224. shift:= [];
  225. exit;
  226. end else
  227. if CompareMem(@utf8ch, @vki.KeyChar[1], sizeof(utf8ch)) then begin
  228. Result:= k;
  229. shift:= [ssShift];
  230. exit;
  231. end else
  232. if CompareMem(@utf8ch, @vki.KeyChar[2], sizeof(utf8ch)) then begin
  233. Result:= k;
  234. shift:= [ssAltGr, ssAlt, ssCtrl];
  235. exit;
  236. end;
  237. end;
  238. end;
  239. {$ENDIF}
  240. end.