Initial import
This commit is contained in:
parent
00d76ab257
commit
9606ce7d4f
|
@ -0,0 +1,212 @@
|
|||
{$I M_OPS.PAS} {$R-}
|
||||
|
||||
Unit m_Input_Windows;
|
||||
|
||||
Interface
|
||||
|
||||
Uses
|
||||
Windows;
|
||||
|
||||
Type
|
||||
TInputWindows = Class
|
||||
ConIn : THandle;
|
||||
Buffer : Array[1..64] of Char;
|
||||
BufPos : Byte;
|
||||
BufSize : Byte;
|
||||
DoingNumChars : Boolean;
|
||||
DoingNumCode : Byte;
|
||||
|
||||
Constructor Create;
|
||||
Destructor Destroy; Override;
|
||||
Procedure AddBuffer (Ch: Char);
|
||||
Function RemapScanCode (ScanCode: Word; CtrlKeyState: dWord; Keycode: Word) : Byte;
|
||||
Function ProcessQueue : Boolean;
|
||||
Function KeyWait (MS: LongInt) : Boolean;
|
||||
Function KeyPressed : Boolean;
|
||||
Function ReadKey : Char;
|
||||
End;
|
||||
|
||||
Implementation
|
||||
|
||||
Constructor TInputWindows.Create;
|
||||
Begin
|
||||
Inherited Create;
|
||||
|
||||
ConIn := GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
SetConsoleMode (ConIn, 0);
|
||||
|
||||
BufPos := 0;
|
||||
BufSize := 0;
|
||||
End;
|
||||
|
||||
Destructor TInputWindows.Destroy;
|
||||
Begin
|
||||
Inherited Destroy;
|
||||
End;
|
||||
|
||||
Procedure TInputWindows.AddBuffer (Ch: Char);
|
||||
Begin
|
||||
Inc (BufSize);
|
||||
|
||||
If BufSize > 64 Then BufSize := 1;
|
||||
|
||||
Buffer[BufSize] := Ch;
|
||||
End;
|
||||
|
||||
Function TInputWindows.RemapScanCode (ScanCode: Word; CtrlKeyState: dWord; keycode: Word) : Byte;
|
||||
Var
|
||||
AltKey,
|
||||
CtrlKey,
|
||||
ShiftKey : Boolean;
|
||||
Const
|
||||
CtrlKeypadKeys: Array[$47..$53] of Byte = (
|
||||
$77,
|
||||
$8D,
|
||||
$84,
|
||||
$8E,
|
||||
$73,
|
||||
$8F,
|
||||
$74,
|
||||
$4E,
|
||||
$75,
|
||||
$91,
|
||||
$76,
|
||||
$92,
|
||||
$93
|
||||
);
|
||||
Begin
|
||||
AltKey := ((CtrlKeyState AND (RIGHT_ALT_PRESSED OR LEFT_ALT_PRESSED)) > 0);
|
||||
CtrlKey := ((CtrlKeyState AND (RIGHT_CTRL_PRESSED OR LEFT_CTRL_PRESSED)) > 0);
|
||||
ShiftKey := ((CtrlKeyState AND SHIFT_PRESSED) > 0);
|
||||
|
||||
If AltKey Then Begin
|
||||
Case KeyCode of
|
||||
VK_NUMPAD0 ..
|
||||
VK_NUMPAD9 : Begin
|
||||
DoingNumChars := True;
|
||||
DoingNumCode := Byte((DoingNumCode * 10) + (KeyCode - VK_NUMPAD0));
|
||||
End;
|
||||
End;
|
||||
|
||||
Case ScanCode of
|
||||
$02..$0D: Inc(ScanCode, $76); // Digits, -, =
|
||||
$3B..$44: Inc(ScanCode, $2D); // Function keys
|
||||
$57..$58: Inc(ScanCode, $34); // Function keys
|
||||
$47..$49,
|
||||
$4B, $4D,
|
||||
$4F..$53: Inc(ScanCode, $50);
|
||||
$1C : ScanCode := $A6; // Enter
|
||||
$35 : ScanCode := $A4; // /
|
||||
End
|
||||
End Else If CtrlKey Then
|
||||
Case ScanCode of
|
||||
$0F : ScanCode := $94; // TAB
|
||||
$3B..$44: Inc(ScanCode, $23); // Function keys
|
||||
$57..$58: Inc(ScanCode, $32); // Function keys
|
||||
$35: ScanCode := $95; // \
|
||||
$37: ScanCode := $96; // *
|
||||
$47..$53: ScanCode := CtrlKeypadKeys[ScanCode];
|
||||
End
|
||||
Else If ShiftKey Then
|
||||
Case ScanCode of
|
||||
$3B..$44: Inc(ScanCode, $19);
|
||||
$57..$58: Inc(ScanCode, $30);
|
||||
End
|
||||
Else
|
||||
Case ScanCode of
|
||||
$57..$58: Inc(Scancode, $2E); // F11 and F12
|
||||
End;
|
||||
|
||||
Result := ScanCode;
|
||||
End;
|
||||
|
||||
Function TInputWindows.ProcessQueue : Boolean;
|
||||
Var
|
||||
InputRec : TInputRecord;
|
||||
NumRead : ULong;
|
||||
Begin
|
||||
Result := False;
|
||||
|
||||
Repeat
|
||||
ReadConsoleInput(ConIn, InputRec, 1, NumRead);
|
||||
|
||||
If InputRec.EventType = key_event then
|
||||
If InputRec.Event.KeyEvent.bKeyDown then begin
|
||||
If not(InputRec.Event.KeyEvent.wVirtualKeyCode in [VK_SHIFT, VK_MENU, VK_CONTROL, VK_CAPITAL, VK_NUMLOCK, VK_SCROLL]) then begin
|
||||
If (Ord(InputRec.Event.KeyEvent.AsciiChar) = 0) or (InputRec.Event.KeyEvent.dwControlKeyState and (LEFT_ALT_PRESSED or ENHANCED_KEY or RIGHT_ALT_PRESSED) > 0) Then Begin
|
||||
If (Ord(InputRec.Event.KeyEvent.AsciiChar) = 13) and (InputRec.Event.KeyEvent.wVirtualKeyCode = VK_RETURN) Then Begin
|
||||
addBuffer(#13);
|
||||
Result := True;
|
||||
Exit;
|
||||
End Else Begin
|
||||
addBuffer(#0);
|
||||
addBuffer(Chr(RemapScanCode(InputRec.Event.KeyEvent.wVirtualScanCode, InputRec.Event.KeyEvent.dwControlKeyState, InputRec.Event.KeyEvent.wVirtualKeyCode)));
|
||||
Result := True;
|
||||
Exit;
|
||||
End;
|
||||
End Else Begin
|
||||
addBuffer(Chr(Ord(InputRec.Event.KeyEvent.AsciiChar)));
|
||||
Result := True;
|
||||
Exit;
|
||||
End;
|
||||
end;
|
||||
End Else
|
||||
If (InputRec.Event.KeyEvent.wVirtualKeyCode in [VK_MENU]) Then
|
||||
If DoingNumChars Then
|
||||
If DoingNumCode > 0 Then Begin
|
||||
AddBuffer(Chr(DoingNumCode));
|
||||
|
||||
DoingNumChars := False;
|
||||
DoingNumCode := 0;
|
||||
|
||||
Result := True;
|
||||
Break;
|
||||
End;
|
||||
|
||||
GetNumberOfConsoleInputEvents(ConIn, NumRead);
|
||||
Until NumRead = 0;
|
||||
End;
|
||||
|
||||
Function TInputWindows.KeyWait (MS: LongInt) : Boolean;
|
||||
Begin
|
||||
If BufPos <> BufSize Then Begin
|
||||
Result := True;
|
||||
Exit;
|
||||
End;
|
||||
|
||||
Repeat
|
||||
Case WaitForSingleObject(ConIn, MS) of
|
||||
Wait_Object_0 : Result := ProcessQueue;
|
||||
Else
|
||||
Result := False;
|
||||
Break;
|
||||
End;
|
||||
Until Result;
|
||||
End;
|
||||
|
||||
Function TInputWindows.ReadKey : Char;
|
||||
Begin
|
||||
If BufPos = BufSize then
|
||||
keyWait (Infinite);
|
||||
|
||||
Inc (BufPos);
|
||||
|
||||
If BufPos > 64 Then BufPos := 1;
|
||||
|
||||
Result := Buffer[BufPos];
|
||||
End;
|
||||
|
||||
Function TInputWindows.KeyPressed : Boolean;
|
||||
Var
|
||||
Temp : ULong;
|
||||
Begin
|
||||
If BufPos = BufSize Then Begin
|
||||
GetNumberOfConsoleInputEvents(ConIn, Temp);
|
||||
If Temp > 0 Then keyWait(1);
|
||||
End;
|
||||
|
||||
Result := BufPos <> BufSize;
|
||||
End;
|
||||
|
||||
End.
|
Loading…
Reference in New Issue