unit uutlKeyCodes; { Package: Utils Prefix: utl - UTiLs Beschreibung: diese Unit enthält alle virtuellen Key Codes } {$mode objfpc}{$H+} interface uses Classes; {$REGION SCANCODES} const VK_UNKNOWN = 0; // defined by LCL VK_LBUTTON = 1; VK_RBUTTON = 2; VK_CANCEL = 3; VK_MBUTTON = 4; VK_XBUTTON1 = 5; VK_XBUTTON2 = 6; VK_BACK = 8; // The "Backspace" key, dont confuse with the // Android BACK key which is mapped to VK_ESCAPE VK_TAB = 9; VK_CLEAR = 12; VK_RETURN = 13; // The "Enter" key, also used for a keypad center press VK_SHIFT = 16; // See also VK_LSHIFT, VK_RSHIFT VK_CONTROL = 17; // See also VK_LCONTROL, VK_RCONTROL VK_MENU = 18; // The ALT key. Also called "Option" in Mac OS X. See also VK_LMENU, VK_RMENU VK_PAUSE = 19; // Pause/Break key VK_CAPITAL = 20; // CapsLock key VK_KANA = 21; VK_HANGUL = 21; VK_JUNJA = 23; VK_FINAL = 24; VK_HANJA = 25; VK_KANJI = 25; VK_ESCAPE = 27; // Also used for the hardware Back key in Android VK_CONVERT = 28; VK_NONCONVERT = 29; VK_ACCEPT = 30; VK_MODECHANGE = 31; VK_SPACE = 32; VK_PRIOR = 33; // Page Up VK_NEXT = 34; // Page Down VK_END = 35; VK_HOME = 36; VK_LEFT = 37; VK_UP = 38; VK_RIGHT = 39; VK_DOWN = 40; VK_SELECT = 41; VK_PRINT = 42; // PrintScreen key VK_EXECUTE = 43; VK_SNAPSHOT = 44; VK_INSERT = 45; VK_DELETE = 46; VK_HELP = 47; VK_0 = $30; VK_1 = $31; VK_2 = $32; VK_3 = $33; VK_4 = $34; VK_5 = $35; VK_6 = $36; VK_7 = $37; VK_8 = $38; VK_9 = $39; //3A-40 Undefined VK_A = $41; VK_B = $42; VK_C = $43; VK_D = $44; VK_E = $45; VK_F = $46; VK_G = $47; VK_H = $48; VK_I = $49; VK_J = $4A; VK_K = $4B; VK_L = $4C; VK_M = $4D; VK_N = $4E; VK_O = $4F; VK_P = $50; VK_Q = $51; VK_R = $52; VK_S = $53; VK_T = $54; VK_U = $55; VK_V = $56; VK_W = $57; VK_X = $58; VK_Y = $59; VK_Z = $5A; VK_LWIN = $5B; // In Mac OS X this is the Apple, or Command key. Windows Key in PC keyboards VK_RWIN = $5C; // In Mac OS X this is the Apple, or Command key. Windows Key in PC keyboards VK_APPS = $5D; // The PopUp key in PC keyboards // $5E reserved VK_SLEEP = $5F; VK_NUMPAD0 = 96; // $60 VK_NUMPAD1 = 97; VK_NUMPAD2 = 98; VK_NUMPAD3 = 99; VK_NUMPAD4 = 100; VK_NUMPAD5 = 101; VK_NUMPAD6 = 102; VK_NUMPAD7 = 103; VK_NUMPAD8 = 104; VK_NUMPAD9 = 105; VK_MULTIPLY = 106; // VK_MULTIPLY up to VK_DIVIDE are usually in the numeric keypad in PC keyboards VK_ADD = 107; VK_SEPARATOR = 108; VK_SUBTRACT = 109; VK_DECIMAL = 110; VK_DIVIDE = 111; VK_F1 = 112; VK_F2 = 113; VK_F3 = 114; VK_F4 = 115; VK_F5 = 116; VK_F6 = 117; VK_F7 = 118; VK_F8 = 119; VK_F9 = 120; VK_F10 = 121; VK_F11 = 122; VK_F12 = 123; VK_F13 = 124; VK_F14 = 125; VK_F15 = 126; VK_F16 = 127; VK_F17 = 128; VK_F18 = 129; VK_F19 = 130; VK_F20 = 131; VK_F21 = 132; VK_F22 = 133; VK_F23 = 134; VK_F24 = 135; // $87 // $88-$8F unassigned VK_NUMLOCK = $90; VK_SCROLL = $91; {$ENDREGION} function CharCodeToVKCode(Ch: WideChar; out shift: TShiftState): word; function VKCodeToCharCode(key: word; Shift: TShiftState): WideChar; implementation {$IFDEF WINDOWS} uses Windows; function CharCodeToVKCode(Ch: WideChar; out shift: TShiftState): word; var st: SmallInt; begin shift:= []; Result:= 0; if ch=#0 then exit; st:= VkKeyScan(AnsiChar(UnicodeChar(ch))); if (hi(st)=$FF) and (lo(st)=$FF) then exit; Result:= lo(st); if Result and (1 shl 8) > 0 then include(shift, ssShift); if Result and (2 shl 8) > 0 then include(shift, ssCtrl); if Result and (4 shl 8) > 0 then include(shift, ssAlt); if [ssCtrl, ssAlt] - shift = [] then include(shift, ssAltGr); end; function VKCodeToCharCode(key: word; Shift: TShiftState): WideChar; var sc: word; ks: array[0..255] of byte; buf: array[0..1] of AnsiChar; begin Result:= #0; sc:= MapVirtualKey(key, {MAPVK_VK_TO_VSC} 0); FillChar({%H-}ks[0], sizeof(ks), 0); if ssShift in Shift then ks[VK_SHIFT]:= $80; if ssCtrl in Shift then ks[VK_CONTROL]:= $80; if ssAlt in Shift then ks[VK_MENU]:= $80; if ssCaps in Shift then ks[VK_CAPITAL]:= $81; buf:= #0#0; case ToAscii(key, sc, @ks[0], LPWORD(@buf[0]), 0) of 0: Result:= #0;//The specified virtual key has no translation for the current state of the keyboard. 1: Result:= UnicodeChar(AnsiChar(buf[0]));//One character was copied to the buffer 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. end; end; {$ELSE} uses SysUtils, gtk2proc; function VKCodeToCharCode(key: word; Shift: TShiftState): WideChar; var vki: TVKeyInfo; dt: PAnsiChar; begin Result:= #0; vki:= GetVKeyInfo(Key); if strlen(vki.KeyChar[0])>0 then begin dt:= ''; if []=Shift then dt:= vki.KeyChar[0] else if ([ssShift]=Shift) or ([ssCaps]=Shift) then dt:= vki.KeyChar[1] else if ([ssCtrl, ssAlt]=Shift) or ([ssAltGr]=Shift) then dt:= vki.KeyChar[2]; Utf8ToUnicode(@Result, 1, PChar(dt), strlen(dt)); end; end; function CharCodeToVKCode(Ch: WideChar; out shift: TShiftState): word; var k: Word; vki: TVKeyInfo; utf8ch: array[0..high(TVKeyUTF8Char)] of AnsiChar; begin Result:= 0; if ch=#0 then exit; utf8ch:= #0#0#0#0#0#0#0#0; //wat UnicodeToUTF8(@utf8ch[0], sizeof(utf8ch), @ch, 1); for k:= low(byte) to high(byte) do begin vki:= GetVKeyInfo(k); if CompareMem(@utf8ch, @vki.KeyChar[0], sizeof(utf8ch)) then begin Result:= k; shift:= []; exit; end else if CompareMem(@utf8ch, @vki.KeyChar[1], sizeof(utf8ch)) then begin Result:= k; shift:= [ssShift]; exit; end else if CompareMem(@utf8ch, @vki.KeyChar[2], sizeof(utf8ch)) then begin Result:= k; shift:= [ssAltGr, ssAlt, ssCtrl]; exit; end; end; end; {$ENDIF} end.