From 9606ce7d4f48268439a4828680ddb849eac87f0b Mon Sep 17 00:00:00 2001 From: mysticbbs Date: Mon, 13 Feb 2012 18:53:50 -0500 Subject: [PATCH] Initial import --- mdl/m_input_windows.pas | 212 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 mdl/m_input_windows.pas diff --git a/mdl/m_input_windows.pas b/mdl/m_input_windows.pas new file mode 100644 index 0000000..b18fd6c --- /dev/null +++ b/mdl/m_input_windows.pas @@ -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.