Author: Jonas Bilinkevicius How to get the scan code of keyboards Answer: 1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs; 8 9 type 10 TKeyInfo = packed record 11 KeyDown: Boolean; 12 VirtualKeyCode: WORD; 13 RepeatCount: Word; 14 VirtualScanCode: Byte; 15 ExtendedKey: Boolean; 16 ContextCode: Boolean; 17 PreviousState: Boolean; 18 AsciiChar: Char; 19 ControlKeyState: DWORD; 20 end; 21 22 TForm1 = class(TForm) 23 private 24 procedure WMKeyDown(var message: TMessage); message WM_KEYDOWN; 25 function GetKeyInfo(var message: TMessage): TKeyInfo; 26 public 27 { Public declarations } 28 end; 29 30 var 31 Form1: TForm1; 32 33 implementation 34 35 {$R *.dfm} 36 37 procedure TForm1.WMKeyDown(var message: TMessage); 38 var 39 KeyInfo: TKeyInfo; 40 begin 41 KeyInfo := GetKeyInfo(message); 42 KeyInfo.KeyDown := True; 43 ShowMessage('ScanCode: ' + IntToStr(KeyInfo.VirtualScanCode)); 44 end; 45 46 function TForm1.GetKeyInfo(var message: TMessage): TKeyInfo; 47 48 function IsWinNT: Boolean; 49 begin 50 Result := (GetVersion < $80000000); 51 end; 52 53 const 54 AltMask = $20000000; 55 var 56 KeyBoardState: TKeyBoardState; 57 LowerKeyData: WORD; 58 UpperKeyData: WORD; 59 begin 60 ZeroMemory(@Result, SizeOf(TKeyInfo)); 61 GetKeyBoardState(KeyBoardState); 62 LowerKeyData := LOWORD(message.LParam); 63 UpperKeyData := HIWORD(message.LParam); 64 Result.VirtualKeyCode := WORD(message.WParam); 65 Result.RepeatCount := LowerKeyData; 66 Result.VirtualScanCode := UpperKeyData and $FF; 67 Result.ExtendedKey := Boolean((UpperKeyData and KF_EXTENDED) shr 8); 68 Result.ContextCode := Boolean((UpperKeyData and KF_ALTDOWN) shr 13); 69 Result.PreviousState := Boolean((UpperKeyData and KF_REPEAT) shr 14); 70 Result.KeyDown := not Boolean((UpperKeyData and KF_UP) shr 15); 71 ToAscii(Result.VirtualKeyCode, Result.VirtualScanCode, KeyBoardState, 72 @Result.AsciiChar, 0); 73 Result.ControlKeyState := (((KeyBoardState[VK_LCONTROL] and 128) shr 7) * 74 LEFT_CTRL_PRESSED) or (((KeyBoardState[VK_RCONTROL] and 128) 75 shr 7) * RIGHT_CTRL_PRESSED) or (((KeyBoardState[VK_LMENU] and 76 128) shr 7) * LEFT_ALT_PRESSED) or (((KeyBoardState[VK_RMENU] 77 and 128) shr 7) * RIGHT_ALT_PRESSED) or ((KeyBoardState 78 [VK_CAPITAL] and 1) * CAPSLOCK_ON) or ((KeyBoardState 79 [VK_NUMLOCK] and 1) * NUMLOCK_ON) or ((KeyBoardState 80 [VK_SCROLL] and 1) * SCROLLLOCK_ON) or ((((KeyBoardState 81 [VK_LSHIFT] or KeyBoardState[VK_RSHIFT]) and 128) shr 7) * 82 SHIFT_PRESSED) or (Integer(Result.ExtendedKey) * ENHANCED_KEY); 83 84 if (not IsWinNT) then 85 begin 86 if (((Result.ControlKeyState and LEFT_CTRL_PRESSED) or (Result.ControlKeyState 87 and 88 RIGHT_CTRL_PRESSED)) = 0) and ((KeyBoardState[VK_CONTROL] and 128) <> 0) then 89 Result.ControlKeyState := Result.ControlKeyState or RIGHT_CTRL_PRESSED; 90 if (((Result.ControlKeyState and LEFT_ALT_PRESSED) or (Result.ControlKeyState 91 and 92 RIGHT_ALT_PRESSED)) = 0) and ((KeyBoardState[VK_MENU] and 128) <> 0) then 93 Result.ControlKeyState := Result.ControlKeyState or RIGHT_ALT_PRESSED; 94 end; 95 end; 96 97 end.