Mirror

How to get the scan code of keyboards (Views: 101)


Problem/Question/Abstract:

How to get the scan code of keyboards

Answer:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;

type
  TKeyInfo = packed record
    KeyDown: Boolean;
    VirtualKeyCode: WORD;
    RepeatCount: Word;
    VirtualScanCode: Byte;
    ExtendedKey: Boolean;
    ContextCode: Boolean;
    PreviousState: Boolean;
    AsciiChar: Char;
    ControlKeyState: DWORD;
  end;

  TForm1 = class(TForm)
  private
    procedure WMKeyDown(var Message: TMessage); message WM_KEYDOWN;
    function GetKeyInfo(var Message: TMessage): TKeyInfo;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WMKeyDown(var Message: TMessage);
var
  KeyInfo: TKeyInfo;
begin
  KeyInfo := GetKeyInfo(Message);
  KeyInfo.KeyDown := True;
  ShowMessage('ScanCode: ' + IntToStr(KeyInfo.VirtualScanCode));
end;

function TForm1.GetKeyInfo(var Message: TMessage): TKeyInfo;

  function IsWinNT: Boolean;
  begin
    Result := (GetVersion < $80000000);
  end;

const
  AltMask = $20000000;
var
  KeyBoardState: TKeyBoardState;
  LowerKeyData: WORD;
  UpperKeyData: WORD;
begin
  ZeroMemory(@Result, SizeOf(TKeyInfo));
  GetKeyBoardState(KeyBoardState);
  LowerKeyData := LOWORD(Message.LParam);
  UpperKeyData := HIWORD(Message.LParam);
  Result.VirtualKeyCode := WORD(Message.WParam);
  Result.RepeatCount := LowerKeyData;
  Result.VirtualScanCode := UpperKeyData and $FF;
  Result.ExtendedKey := Boolean((UpperKeyData and KF_EXTENDED) shr 8);
  Result.ContextCode := Boolean((UpperKeyData and KF_ALTDOWN) shr 13);
  Result.PreviousState := Boolean((UpperKeyData and KF_REPEAT) shr 14);
  Result.KeyDown := not Boolean((UpperKeyData and KF_UP) shr 15);
  ToAscii(Result.VirtualKeyCode, Result.VirtualScanCode, KeyBoardState,
    @Result.AsciiChar, 0);
  Result.ControlKeyState := (((KeyBoardState[VK_LCONTROL] and 128) shr 7) *
    LEFT_CTRL_PRESSED) or (((KeyBoardState[VK_RCONTROL] and 128)
    shr 7) * RIGHT_CTRL_PRESSED) or (((KeyBoardState[VK_LMENU] and
    128) shr 7) * LEFT_ALT_PRESSED) or (((KeyBoardState[VK_RMENU]
    and 128) shr 7) * RIGHT_ALT_PRESSED) or ((KeyBoardState
    [VK_CAPITAL] and 1) * CAPSLOCK_ON) or ((KeyBoardState
    [VK_NUMLOCK] and 1) * NUMLOCK_ON) or ((KeyBoardState
    [VK_SCROLL] and 1) * SCROLLLOCK_ON) or ((((KeyBoardState
    [VK_LSHIFT] or KeyBoardState[VK_RSHIFT]) and 128) shr 7) *
    SHIFT_PRESSED) or (Integer(Result.ExtendedKey) * ENHANCED_KEY);

  if (not IsWinNT) then
  begin
    if (((Result.ControlKeyState and LEFT_CTRL_PRESSED) or (Result.ControlKeyState and
      RIGHT_CTRL_PRESSED)) = 0) and ((KeyBoardState[VK_CONTROL] and 128) <> 0) then
      Result.ControlKeyState := Result.ControlKeyState or RIGHT_CTRL_PRESSED;
    if (((Result.ControlKeyState and LEFT_ALT_PRESSED) or (Result.ControlKeyState and
      RIGHT_ALT_PRESSED)) = 0) and ((KeyBoardState[VK_MENU] and 128) <> 0) then
      Result.ControlKeyState := Result.ControlKeyState or RIGHT_ALT_PRESSED;
  end;
end;

end.

<< Back to main page