public void SendKeyPress(int charCode) { //foreach(char key in keys) //{ char key = (char)charCode; char keyU = key.ToString().ToUpper().ToCharArray()[0]; uint STD_INPUT_HANDLE = 0xfffffff6; IntPtr hConsoleInput = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD[] iR = new INPUT_RECORD[] { new INPUT_RECORD() { KeyEvent = new KEY_EVENT_RECORD() { bKeyDown = true, UnicodeChar = key, wVirtualKeyCode = (VirtualKeys)keyU }, EventType = 0x1 } }; uint eventsWritten; WriteConsoleInput(hConsoleInput, iR, 1, out eventsWritten); //} }
private KeyInfo PollKeyboard() { INPUT_RECORD [] record = new INPUT_RECORD[1]; uint count; PeekConsoleInput(input, record, 1, out count); if (count == 0) { return(null); } ReadConsoleInput(input, record, 1, out count); if (count == 0) { return(null); } if (record[0].EventType == KEY_EVENT && record[0].KeyEvent.bKeyDown) { return(Translate(record[0])); } return(null); }
public void Run() { var exitKeyPressed = false; var nRead = 0; var records = new INPUT_RECORD[10]; var handle = GetStdHandle(STD_INPUT_HANDLE); while (!exitKeyPressed) { ReadConsoleInputW(handle, records, records.Length, ref nRead); for (var i = 0; i < nRead; i++) { // process only Key events if (records[i].EventType != KEY_EVENT) { continue; } // process key state ProcessKey(records[i].KeyEvent.wVirtualKeyCode, records[i].KeyEvent.bKeyDown, records[i].KeyEvent.UnicodeChar); // check for exit key press if ((exitKeyPressed = records[i].KeyEvent.wVirtualKeyCode == _exitKey) == true) { break; } } } }
public INPUT_RECORD[] ReadConsoleInput(ConsoleInputHandle consoleInputHandle, int maxElements = 1028) { INPUT_RECORD[] result = new INPUT_RECORD[maxElements]; if (!NativeMethods.ReadConsoleInput(consoleInputHandle, result, maxElements, out var read)) { throw Exceptions.Win32(); } return(result.Take(read).ToArray()); }
public static void Start() { if (!Run) { Run = true; IntPtr handleIn = GetStdHandle(STD_INPUT_HANDLE); new Thread(() => { while (true) { uint numRead = 0; INPUT_RECORD[] record = new INPUT_RECORD[1]; record[0] = new INPUT_RECORD(); ReadConsoleInput(handleIn, record, 1, ref numRead); if (Run) { switch (record[0].EventType) { case INPUT_RECORD.MOUSE_EVENT: MouseEvent?.Invoke(record[0].MouseEvent); switch (record[0].MouseEvent.dwButtonState) { case MOUSE_EVENT_RECORD.FROM_LEFT_1ST_BUTTON_PRESSED: ClickEvent?.Invoke(record[0].MouseEvent); break; case MOUSE_EVENT_RECORD.SCROLLED_UP: ScrollUpEvent?.Invoke(record[0].MouseEvent); break; case MOUSE_EVENT_RECORD.SCROLLED_DOWN: ScrollDownEvent?.Invoke(record[0].MouseEvent); break; } break; case INPUT_RECORD.KEY_EVENT: KeyEvent?.Invoke(record[0].KeyEvent); break; case INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT: WindowBufferSizeEvent?.Invoke(record[0].WindowBufferSizeEvent); break; } } else { uint numWritten = 0; WriteConsoleInput(handleIn, record, 1, ref numWritten); return; } } }).Start(); } }
public void Start() { IntPtr inHandle = GetStdHandle(STD_INPUT_HANDLE); uint mode = 0; GetConsoleMode(inHandle, ref mode); mode &= ~ENABLE_QUICK_EDIT_MODE; //disable mode |= ENABLE_WINDOW_INPUT; //enable (if you want) mode |= ENABLE_MOUSE_INPUT; //enable mode |= 4; SetConsoleMode(inHandle, mode); IntPtr outHandle = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleMode(outHandle, ref mode); mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; SetConsoleMode(outHandle, mode); IntPtr handleIn = GetStdHandle(STD_INPUT_HANDLE); new Thread(() => { while (true) { uint numRead = 0; INPUT_RECORD[] record = new INPUT_RECORD[1]; record[0] = new INPUT_RECORD(); ReadConsoleInput(handleIn, record, 1, ref numRead); switch (record[0].EventType) { case INPUT_RECORD.MOUSE_EVENT: { var e = record[0].MouseEvent; if (e.dwButtonState == MOUSE_EVENT_RECORD.FROM_LEFT_1ST_BUTTON_PRESSED) { onMouseClick?.Invoke(e.dwMousePosition.X, e.dwMousePosition.Y); } break; } /* * case INPUT_RECORD.KEY_EVENT: * KeyEvent?.Invoke(record[0].KeyEvent); * break; * case INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT: * WindowBufferSizeEvent?.Invoke(record[0].WindowBufferSizeEvent); * break; */ } } }).Start(); }
public static void Start() { if (ConsoleInputHandle == IntPtr.Zero) { return; } if (Running) { return; } Running = true; IsEchoInputEnabled = true; IsWindowInputEnabled = true; IsMouseInputEnabled = true; IntPtr handleIn = ConsoleInputHandle; new Thread(() => { while (true) { UInt32 numRead = 0; INPUT_RECORD[] record = new INPUT_RECORD[1]; record[0] = new INPUT_RECORD(); ReadConsoleInput(handleIn, record, 1, ref numRead); if (Running) { switch (record[0].EventType) { case INPUT_RECORD.MOUSE_EVENT: MouseEvent?.Invoke(record[0].MouseEvent); break; case INPUT_RECORD.KEY_EVENT: KeyEvent?.Invoke(record[0].KeyEvent); break; case INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT: WindowBufferSizeEvent?.Invoke(record[0].WindowBufferSizeEvent); break; } } else { UInt32 numWritten = 0; WriteConsoleInput(handleIn, record, 1, ref numWritten); return; } } }).Start(); }
public TvConsoleEvents ReadEvents() { ConsoleNative.GetNumberOfConsoleInputEvents(_hstdin, out var numEvents); if (numEvents > 0) { var buffer = new INPUT_RECORD[numEvents]; ConsoleNative.ReadConsoleInput(_hstdin, buffer, (uint)buffer.Length, out var eventsRead); return(new TvConsoleEvents().Add(buffer)); } else { return(TvConsoleEvents.Empty); } }
public static ushort GetLastPressedCode() { uint nRead = 0; ushort result = 0; INPUT_RECORD[] iRecord = new INPUT_RECORD[128]; if (ReadConsoleInput(stdIn, iRecord, 128, out nRead)) for (int n = (int)nRead -1; n >= 0; n--) if (iRecord[n].EventType == KEY_EVENT) if (iRecord[n].bKeyDown != 0) { result = iRecord[n].wVirtualKeyCode; break; } return result; }
/// <summary> /// Blocks and waits for a console key to be pressed, then returns the keypress value. /// </summary> /// <returns>The virtual key code of the key that was pressed</returns> public static Keys ReadKey() { INPUT_RECORD[] buffer = new INPUT_RECORD[1]; uint events; IntPtr handle = GetStdHandle(STD_INPUT_HANDLE); for (;;) { WaitForSingleObject(handle, INFINITE); ReadConsoleInput(handle, buffer, 1, out events); if (buffer[0].EventType == EventType.Key && buffer[0].KeyEvent.bKeyDown == true) { return((Keys)buffer[0].KeyEvent.wVirtualKeyCode); } } }
private void processInput() { INPUT_RECORD[] buffer = new INPUT_RECORD[10]; uint read; bool bReaded = Win32.ReadConsoleInput(stdInputHandle, buffer, (uint)buffer.Length, out read); if (!bReaded) { throw new InvalidOperationException("ReadConsoleInput method failed."); } for (int i = 0; i < read; ++i) { processInputEvent(buffer[i]); } }
private ConsoleEvent GetConsoleEvent() { // CONSIDER: Any reason to buffer more than one record in our Win32Console class? var records = new INPUT_RECORD[1]; uint count; if (!ReadConsoleInput(_handleIn, records, (uint)records.Length, out count)) { throw new Exception("ReadConsoleInput failed"); } var record = records[0]; switch (record.EventType) { case EventType.KEY_EVENT: { var keyEvent = record.KeyEvent; return(new KeyEvent(keyEvent.bKeyDown, keyEvent.UnicodeChar, keyEvent.wRepeatCount, keyEvent.wVirtualKeyCode, keyEvent.dwControlKeyState)); } case EventType.MOUSE_EVENT: { var mouseEvent = record.MouseEvent; return(new MouseEvent(mouseEvent.dwMousePosition.x, mouseEvent.dwMousePosition.y, mouseEvent.dwButtonState, mouseEvent.dwControlKeyState, mouseEvent.dwEventFlags)); } case EventType.WINDOW_BUFFER_SIZE_EVENT: { COORD size = record.WindowBufferSizeEvent.dwSize; return(new BufferSizeEvent(size.x, size.y)); } case EventType.FOCUS_EVENT: case EventType.MENU_EVENT: { // Ignore. return(null); } default: throw new Exception("Invalid EventType enum value"); } }
public VirtualKeys GetCurrentKey() { INPUT_RECORD[] input = new INPUT_RECORD[128]; while (true) { ReadConsoleInput(_consoleWindowInput, input, 128, out uint num); foreach (var inp in input) { if (inp.EventType != INPUT_RECORD.KEY_EVENT) { continue; } if (!inp.Event.KeyEvent.bKeyDown) { continue; } return(inp.Event.KeyEvent.wVirtualKeyCode); } } }
public static void Start() { if (!run) { run = true; IntPtr handleIn = GetStdHandle(STD_INPUT_HANDLE); new Thread(() => { while (true) { uint numRead = 0; INPUT_RECORD[] record = new INPUT_RECORD[1]; record[0] = new INPUT_RECORD(); ReadConsoleInput(handleIn, record, 1, ref numRead); if (run) { switch (record[0].EventType) { case INPUT_RECORD.MOUSE_EVENT: MouseEvent?.Invoke(record[0].MouseEvent); break; case INPUT_RECORD.KEY_EVENT: KeyEvent?.Invoke(record[0].KeyEvent); break; case INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT: WindowBufferSizeEvent?.Invoke(record[0].WindowBufferSizeEvent); break; } } else { uint numWritten = 0; WriteConsoleInput(handleIn, record, 1, ref numWritten); return; } } }).Start(); } }
static void Main() { int nRead = 0; IntPtr handle = GetStdHandle(-10 /*STD_INPUT_HANDLE*/); Console.Write("Press the letter: 'a': "); INPUT_RECORD record = new INPUT_RECORD(); do { ReadConsoleInputW(handle, ref record, 1, ref nRead); } while (record.EventType != 0x0001 /*KEY_EVENT*/); Assert.AreEqual((short)0x0001, record.EventType); Assert.AreEqual(1u, record.KeyEvent.bKeyDown); Assert.AreEqual(0x00000000, record.KeyEvent.dwControlKeyState & ~0x00000020);//strip num-lock and test Assert.AreEqual('a', record.KeyEvent.UnicodeChar); Assert.AreEqual((short)0x0001, record.KeyEvent.wRepeatCount); Assert.AreEqual((short)0x0041, record.KeyEvent.wVirtualKeyCode); Assert.AreEqual((short)0x001e, record.KeyEvent.wVirtualScanCode); return; }
private void processInputEvent(INPUT_RECORD inputRecord) { if (inputRecord.EventType == EventType.WINDOW_BUFFER_SIZE_EVENT) { if (usingLinux) { // Reinitializing ncurses to deal with new dimensions // http://stackoverflow.com/questions/13707137/ncurses-resizing-glitch NCurses.endwin(); // Needs to be called after an endwin() so ncurses will initialize // itself with the new terminal dimensions. NCurses.refresh(); NCurses.clear(); } COORD dwSize = inputRecord.WindowBufferSizeEvent.dwSize; // Invoke default handler if no custom handlers attached and // userCanvasSize and userRootElementRect are not defined if (TerminalSizeChanged == null && userCanvasSize.IsEmpty && userRootElementRect.IsEmpty) { OnTerminalSizeChangedDefault(this, new TerminalSizeChangedEventArgs(dwSize.X, dwSize.Y)); } else if (TerminalSizeChanged != null) { TerminalSizeChanged.Invoke(this, new TerminalSizeChangedEventArgs(dwSize.X, dwSize.Y)); } // Refresh whole display renderer.FinallyApplyChangesToCanvas(true); return; } eventManager.ParseInputEvent(inputRecord, mainControl); }
public static extern Boolean ReadConsoleInput(ConsoleHandle hConsoleInput, ref INPUT_RECORD lpBuffer, UInt32 nLength, ref UInt32 lpNumberOfEventsRead);
private KeyInfo Translate(INPUT_RECORD record) { KeyInfo key = new KeyInfo(); key.Shift = (record.KeyEvent.dwControlKeyState & SHIFT_PRESSED) != 0; key.Alt = ((record.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED) != 0) || ((record.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED) != 0); key.Ctrl = ((record.KeyEvent.dwControlKeyState & LEFT_CTRL_PRESSED) != 0) || ((record.KeyEvent.dwControlKeyState & RIGHT_CTRL_PRESSED) != 0); switch (record.KeyEvent.wVirtualKeyCode) { case 0x1B: key.KeyCode = Key.Esc; break; case 0x08: key.KeyCode = Key.Backspace; break; case 0x20: key.KeyCode = Key.Space; break; case 0x0D: key.KeyCode = Key.Enter; break; case 0x70: key.KeyCode = Key.F1; break; case 0x71: key.KeyCode = Key.F2; break; case 0x72: key.KeyCode = Key.F3; break; case 0x73: key.KeyCode = Key.F4; break; case 0x74: key.KeyCode = Key.F5; break; case 0x75: key.KeyCode = Key.F6; break; case 0x76: key.KeyCode = Key.F7; break; case 0x77: key.KeyCode = Key.F8; break; case 0x78: key.KeyCode = Key.F9; break; case 0x79: key.KeyCode = Key.F10; break; case 0x7A: key.KeyCode = Key.F11; break; case 0x7B: key.KeyCode = Key.F12; break; case 0x31: key.KeyCode = Key.Key1; break; case 0x32: key.KeyCode = Key.Key2; break; case 0x33: key.KeyCode = Key.Key3; break; case 0x34: key.KeyCode = Key.Key4; break; case 0x35: key.KeyCode = Key.Key5; break; case 0x36: key.KeyCode = Key.Key6; break; case 0x37: key.KeyCode = Key.Key7; break; case 0x38: key.KeyCode = Key.Key8; break; case 0x39: key.KeyCode = Key.Key9; break; case 0x30: key.KeyCode = Key.Key0; break; case 0xC0: key.KeyCode = Key.Tilda; break; case 0xBD: key.KeyCode = Key.KeyMinus; break; case 0xBB: key.KeyCode = Key.KeyPlus; break; case 0x51: key.KeyCode = Key.Q; break; case 0x57: key.KeyCode = Key.W; break; case 0x45: key.KeyCode = Key.E; break; case 0x52: key.KeyCode = Key.R; break; case 0x54: key.KeyCode = Key.T; break; case 0x59: key.KeyCode = Key.Y; break; case 0x55: key.KeyCode = Key.U; break; case 0x49: key.KeyCode = Key.I; break; case 0x4F: key.KeyCode = Key.O; break; case 0x50: key.KeyCode = Key.P; break; case 0x41: key.KeyCode = Key.A; break; case 0x53: key.KeyCode = Key.S; break; case 0x44: key.KeyCode = Key.D; break; case 0x46: key.KeyCode = Key.F; break; case 0x47: key.KeyCode = Key.G; break; case 0x48: key.KeyCode = Key.H; break; case 0x4A: key.KeyCode = Key.J; break; case 0x4B: key.KeyCode = Key.K; break; case 0x4C: key.KeyCode = Key.L; break; case 0x5A: key.KeyCode = Key.Z; break; case 0x58: key.KeyCode = Key.X; break; case 0x43: key.KeyCode = Key.C; break; case 0x56: key.KeyCode = Key.V; break; case 0x42: key.KeyCode = Key.B; break; case 0x4E: key.KeyCode = Key.N; break; case 0x4D: key.KeyCode = Key.M; break; case 0x60: key.KeyCode = Key.Num0; break; case 0x61: key.KeyCode = Key.Num1; break; case 0x62: key.KeyCode = Key.Num2; break; case 0x63: key.KeyCode = Key.Num3; break; case 0x64: key.KeyCode = Key.Num4; break; case 0x65: key.KeyCode = Key.Num5; break; case 0x66: key.KeyCode = Key.Num6; break; case 0x67: key.KeyCode = Key.Num7; break; case 0x68: key.KeyCode = Key.Num8; break; case 0x69: key.KeyCode = Key.Num9; break; case 0x6F: key.KeyCode = Key.NumSlash; break; case 0x6A: key.KeyCode = Key.NumAsterisk; break; case 0x6D: key.KeyCode = Key.NumMinus; break; case 0x6B: key.KeyCode = Key.NumPlus; break; case 0x26: key.KeyCode = Key.Up; break; case 0x28: key.KeyCode = Key.Down; break; case 0x25: key.KeyCode = Key.Left; break; case 0x27: key.KeyCode = Key.Right; break; case 0xDB: key.KeyCode = Key.LSquare; break; case 0xDD: key.KeyCode = Key.RSquare; break; case 0xBA: key.KeyCode = Key.Colon; break; case 0xDE: key.KeyCode = Key.Quotes; break; case 0xDC: key.KeyCode = Key.BackSlash; break; case 0xBC: key.KeyCode = Key.LAngle; break; case 0xBE: key.KeyCode = Key.RAngle; break; case 0xBF: key.KeyCode = Key.Slash; break; case 0x2D: key.KeyCode = Key.Ins; break; case 0x2E: key.KeyCode = Key.Del; break; case 0x24: key.KeyCode = Key.Home; break; case 0x23: key.KeyCode = Key.End; break; case 0x21: key.KeyCode = Key.PageUp; break; case 0x22: key.KeyCode = Key.PageDown; break; } return(key); }
// All event handler functions must return a boolean value indicating whether // the password processing function should continue to read in another console // input record (via ReadConsoleInput() API). // Returning a true indicates continue. // Returning a false indicates don't continue. private bool WindowBufferSizeEventProc(INPUT_RECORD input_record, ref string strBuildup) { // Since our Window Buffer Size Event Handler does not intend to do anything, // we simply return a true to indicate to the password processing // function to readin another console input record. return true; }
/// <summary> /// Blocks and waits for a console key to be pressed, then returns the keypress value. /// </summary> /// <returns>The virtual key code of the key that was pressed</returns> public static Keys ReadKey() { INPUT_RECORD[] buffer = new INPUT_RECORD[1]; uint events; IntPtr handle = GetStdHandle(STD_INPUT_HANDLE); for(;;) { WaitForSingleObject(handle, INFINITE); ReadConsoleInput(handle, buffer, 1, out events); if(buffer[0].EventType == EventType.Key && buffer[0].KeyEvent.bKeyDown == true) return (Keys)buffer[0].KeyEvent.wVirtualKeyCode; } }
// Adapted from https://docs.microsoft.com/en-us/windows/console/reading-input-buffer-events private static int ReadInputEvents() { if (!GetConsoleMode(hStdin, out CONSOLE_INPUT_MODE fdwSaveOldMode)) { return(ShowErr("GetConsoleMode")); } Console.WriteLine($"Orig input mode: {fdwSaveOldMode}"); try { if (!SetConsoleMode(hStdin, CONSOLE_INPUT_MODE.ENABLE_MOUSE_INPUT | CONSOLE_INPUT_MODE.ENABLE_EXTENDED_FLAGS)) { return(ShowErr("SetConsoleMode")); } if (!GetNumberOfConsoleMouseButtons(out var mouseBtn)) { return(ShowErr("GetNumberOfConsoleMouseButtons")); } if (!GetConsoleSelectionInfo(out var selInfo)) { return(ShowErr("GetConsoleSelectionInfo")); } SetConsoleCursorInfo(hStdin, new CONSOLE_CURSOR_INFO { dwSize = 25 }); while (true /*WaitForSingleObject(hStdin, 10000) == WAIT_STATUS.WAIT_OBJECT_0*/) { if (!GetNumberOfConsoleInputEvents(hStdin, out var evtNum)) { return(ShowErr("GetNumberOfConsoleInputEvents")); } if (evtNum == 0) { continue; } var irInBuf = new INPUT_RECORD[evtNum]; //PeekConsoleInput(hStdin, irInBuf, evtNum, out _); if (!ReadConsoleInput(hStdin, irInBuf, evtNum, out var cNumRead)) { return(ShowErr("ReadConsoleInput")); } for (var i = 0; i < cNumRead; i++) { var ir = irInBuf[i]; //Console.WriteLine($"Seeing event {ir.EventType}"); switch (ir.EventType) { case EVENT_TYPE.KEY_EVENT: Console.WriteLine($"Key event: {(ir.Event.KeyEvent.bKeyDown ? "Pressed" : "Released")} Key: {ir.Event.KeyEvent.uChar} (0x{ir.Event.KeyEvent.wVirtualKeyCode:X})"); if (ir.Event.KeyEvent.uChar == 'q') { return(0); } break; case EVENT_TYPE.MOUSE_EVENT: MouseEventProc(ir.Event.MouseEvent); break; case EVENT_TYPE.WINDOW_BUFFER_SIZE_EVENT: //Console.WriteLine($"Screen buffer is {ir.Event.WindowBufferSizeEvent.dwSize}"); break; case EVENT_TYPE.MENU_EVENT: break; case EVENT_TYPE.FOCUS_EVENT: //Console.WriteLine($"Focus event: {(ir.Event.FocusEvent.bSetFocus ? "Got" : "Lost")}"); break; default: return(ShowErr("Unknown event type.")); } } } } finally { SetConsoleMode(hStdin, fdwSaveOldMode); }
public static void InputLoop() { uint toRead = 128; var records = new INPUT_RECORD[toRead]; int prevWidth = MyConsole.Width; int prevHeight = MyConsole.Height; MouseButton prevMouseState = MouseButton.None; COORD prevMouseLocation = new COORD(); while (!MyConsole.Exiting) { WinApi.ReadConsoleInput(inputHandle, records, toRead, out uint recordLen); for (int i = 0; i < recordLen; i++) { var record = records[i]; switch (record.EventType) { case EventType.Mouse: { var mouseEvent = record.Event.MouseEvent; var button = mouseEvent.ButtonState; var flags = mouseEvent.EventFlags; var location = mouseEvent.MousePosition; bool mousePressed = prevMouseState == MouseButton.None && button != MouseButton.None; bool mouseReleased = prevMouseState != MouseButton.None && button == MouseButton.None; bool mouseHeld = prevMouseState != MouseButton.None && button != MouseButton.None; var args = new MouseEventArgs { Button = button, Location = location, ControlKeyState = mouseEvent.ControlKeyState }; bool sameLocation = location.Equals(prevMouseLocation); if (mousePressed && flags.HasFlag(MouseState.DoubleClick)) { MouseDoubleClick?.Invoke(null, args); } else if (mousePressed) { MousePressed?.Invoke(null, args); } else if (mouseReleased) { MouseReleased?.Invoke(null, args); } else if (mouseHeld && flags.HasFlag(MouseState.Moved) && !sameLocation) { MouseDragged?.Invoke(null, args); } else if (flags.HasFlag(MouseState.Moved) && !sameLocation) { MouseMoved?.Invoke(null, args); } prevMouseState = button; prevMouseLocation = location; } break; case EventType.Key: { var keyEvent = record.Event.KeyEvent; var eventArgs = new KeyEventArgs { Key = (ConsoleKey)keyEvent.VirtualKeyCode, ControlKeyState = keyEvent.ControlKeyState }; bool currState = keyEvent.KeyDown; bool prevState = keyStates[keyEvent.VirtualKeyCode]; if (currState && !prevState) { KeyPressed?.Invoke(eventArgs); } else if (prevState && !currState) { KeyReleased?.Invoke(eventArgs); } else if (prevState && currState) { KeyHeld?.Invoke(eventArgs); } keyStates[keyEvent.VirtualKeyCode] = keyEvent.KeyDown; } break; case EventType.Resize: { var clientSize = MyConsole.GetClientSize(); var fontSize = MyConsole.GetFontSize(); int w = clientSize.X / fontSize.X; int h = clientSize.Y / fontSize.Y; if (prevWidth != w || prevHeight != h) { MyConsole.SetSize(w, h); MyConsole.HideCursor(); Drawing.ConsoleRenderer.Resize(w, h); Resized?.Invoke(new ResizedEventArgs { Width = w, Height = h }); prevWidth = w; prevHeight = h; } } break; case EventType.Menu: { var id = record.Event.MenuEvent.dwCommandId; Debug.WriteLine(id); } break; case EventType.Focus: { var focused = record.Event.FocusEvent.bSetFocus; } break; default: Debug.WriteLine("Unhandled event: " + record.EventType); break; } } } }
// Event handler to handle a keyboard event. // We use this function to accumulate characters typed into the console and build // up the password this way. // All event handler functions must return a boolean value indicating whether // the password processing function should continue to read in another console // input record (via ReadConsoleInput() API). // Returning a true indicates continue. // Returning a false indicates don't continue. private bool KeyEventProc(INPUT_RECORD input_record, ref string strBuildup) { // From the INPUT_RECORD, extract the KEY_EVENT_RECORD structure. KEY_EVENT_RECORD ker = input_record.Event.KeyEvent; // We process only during the keydown event. if (ker.bKeyDown != 0) { IntPtr intptr = new IntPtr(0); // This is to simulate a NULL handle value. char ch = (char)(ker.uchar.UnicodeChar); // Get the current character pressed. uint dwNumberOfCharsWritten = 0; string strOutput = "*"; // The character string that will be displayed on the console screen. // If we have received a Carriage Return character, we exit. if (ch == (char)'\r') { return false; } else { if (ch > 0) // The typed in key must represent a character and must not be a control ley (e.g. SHIFT, ALT, CTRL, etc) { // A regular (non Carriage-Return character) is typed in... // We first display a '*' on the screen... WriteConsole ( hStdout, // handle to screen buffer strOutput, // write buffer 1, // number of characters to write ref dwNumberOfCharsWritten, // number of characters written intptr // reserved ); // We build up our password string... string strConcat = new string(ch, 1); // by appending each typed in character at the end of strBuildup. strBuildup += strConcat; if (++iCounter < MaxNumberOfCharacters) { // Adding 1 to iCounter still makes iCounter less than MaxNumberOfCharacters. // This means that the total number of characters collected so far (this is // equal to iCounter, by the way) is less than MaxNumberOfCharacters. // We can carry on. return true; } else { // If, by adding 1 to iCounter makes iCounter greater than MaxNumberOfCharacters, // it means that we have already collected MaxNumberOfCharacters number of characters // inside strBuildup. We must exit now. return false; } } } } // The keydown state is false, we allow further characters to be typed in... return true; }
public void TestMethod() { // Taken from https://docs.microsoft.com/en-us/windows/console/reading-input-buffer-events var hStdin = GetStdHandle(StdHandleType.STD_INPUT_HANDLE); if (hStdin.IsInvalid) { Win32Error.ThrowLastError(); } if (!GetConsoleMode(hStdin, out CONSOLE_INPUT_MODE fewSaveOldMode)) { Win32Error.ThrowLastError(); } try { if (!SetConsoleMode(hStdin, CONSOLE_INPUT_MODE.ENABLE_WINDOW_INPUT | CONSOLE_INPUT_MODE.ENABLE_MOUSE_INPUT)) { Win32Error.ThrowLastError(); } var counter = 0; const int recCnt = 128; while (counter++ <= 100) { var irInBuf = new INPUT_RECORD[recCnt]; if (!ReadConsoleInput(hStdin, irInBuf, recCnt, out var cNumRead)) { Win32Error.ThrowLastError(); } for (var i = 0; i < cNumRead; i++) { switch (irInBuf[i].EventType) { case EVENT_TYPE.KEY_EVENT: TestContext.WriteLine($"Key event: {(irInBuf[i].Event.KeyEvent.bKeyDown ? "Pressed" : "Released")}"); break; case EVENT_TYPE.MOUSE_EVENT: MouseEventProc(irInBuf[i].Event.MouseEvent); break; case EVENT_TYPE.WINDOW_BUFFER_SIZE_EVENT: TestContext.WriteLine($"Screen buffer is {irInBuf[i].Event.WindowBufferSizeEvent.dwSize.X} x {irInBuf[i].Event.WindowBufferSizeEvent.dwSize.Y}"); break; case EVENT_TYPE.MENU_EVENT: case EVENT_TYPE.FOCUS_EVENT: break; default: throw new InvalidOperationException("Unknown event type."); } } } } finally { SetConsoleMode(hStdin, fewSaveOldMode); } void MouseEventProc(MOUSE_EVENT_RECORD mouseEvent) { TestContext.Write("Mouse event: "); switch (mouseEvent.dwEventFlags) { case MOUSE_EVENT_FLAG.NONE: if (mouseEvent.dwButtonState == MOUSE_BUTTON_STATE.FROM_LEFT_1ST_BUTTON_PRESSED) { TestContext.WriteLine("Left btn press"); } else if (mouseEvent.dwButtonState == MOUSE_BUTTON_STATE.RIGHTMOST_BUTTON_PRESSED) { TestContext.WriteLine("Right btn press"); } else { TestContext.WriteLine("Btn press"); } break; case MOUSE_EVENT_FLAG.DOUBLE_CLICK: TestContext.WriteLine("Double click"); break; case MOUSE_EVENT_FLAG.MOUSE_HWHEELED: TestContext.WriteLine("Horz mouse wheeled"); break; case MOUSE_EVENT_FLAG.MOUSE_MOVED: TestContext.WriteLine("Mouse moved"); break; case MOUSE_EVENT_FLAG.MOUSE_WHEELED: TestContext.WriteLine("Vert mouse wheeled"); break; default: TestContext.WriteLine("Unknown"); break; } } }
internal static partial bool ReadConsoleInput(IntPtr hConsoleInput, out INPUT_RECORD buffer, int numInputRecords_UseOne, out int numEventsRead);
private void GameThread() { if (!OnUserCreate()) { return; } var tp1 = DateTime.Now.Millisecond; var tp2 = DateTime.Now.Millisecond; while (m_bAtomActive) { tp2 = DateTime.Now.Millisecond; float elapsed = Math.Abs(tp2 - tp1); tp1 = tp2; #region Input Handling #region Keyboard for (int i = 0; i < 256; i++) { m_keyNewState[i] = GetAsyncKeyState(i); m_keys[i].bPressed = false; m_keys[i].bReleased = false; if (m_keyNewState[i] != m_keyOldState[i]) { if (Convert.ToBoolean(m_keyNewState[i] & 0x8000)) { m_keys[i].bPressed = !m_keys[i].bHeld; m_keys[i].bHeld = true; } else { m_keys[i].bReleased = true; m_keys[i].bHeld = false; } } m_keyOldState[i] = m_keyNewState[i]; } #endregion #region Mouse INPUT_RECORD[] inBuf = new INPUT_RECORD[32]; uint events = 0; GetNumberOfConsoleInputEvents(m_hConsoleIn, out events); if (events > 0) { ReadConsoleInput(m_hConsoleIn, inBuf, events, out events); } for (uint i = 0; i < events; i++) { if (inBuf[i].EventType == 0x0002 || (inBuf[i].MouseEvent.dwEventFlags == 0 || inBuf[i].MouseEvent.dwEventFlags == 0x0001)) { if (inBuf[i].MouseEvent.dwEventFlags == 0) { for (int m = 0; m < 5; m++) { m_mouseNewState[m] = (inBuf[i].MouseEvent.dwButtonState & (1 << m)) > 0; } } else { m_mousePosX = inBuf[i].MouseEvent.dwMousePosition.X; m_mousePosY = inBuf[i].MouseEvent.dwMousePosition.Y; } } } for (int m = 0; m < 5; m++) { m_mouse[m].bPressed = false; m_mouse[m].bReleased = false; if (m_mouseNewState[m] != m_mouseOldState[m]) { if (m_mouseNewState[m]) { m_mouse[m].bPressed = true; m_mouse[m].bHeld = true; } else { m_mouse[m].bReleased = true; m_mouse[m].bHeld = false; } } m_mouseOldState[m] = m_mouseNewState[m]; } #endregion #endregion if (!OnUserUpdate(elapsed)) { m_bAtomActive = false; } SetConsoleTitle(string.Format("OneLoneCoder.com - Console Game Engine - {0} s - FPS: {1}", m_sAppName, elapsed)); COORD coord; coord.X = (short)m_nScreenWidth; coord.Y = (short)m_nScreenHeight; COORD c; c.X = 0; c.Y = 0; Console.OutputEncoding = Encoding.Unicode; Console.CursorVisible = false; WriteConsoleOutput(m_hConsole, m_bufScreen, coord, c, ref m_rectWindow); } }
public static extern bool ReadConsoleInputW(IntPtr hConsoleInput, ref INPUT_RECORD lpBuffer, int nLength, ref int lpNumberOfEventsRead);
/// <summary> /// Wraps Win32 PeekConsoleInput /// </summary> /// <param name="consoleHandle"> /// /// handle for the console where input is peeked /// /// </param> /// <param name="buffer"> /// /// array where data read are stored /// /// </param> /// <returns> /// /// actual number of input records peeked /// /// </returns> /// <exception cref="HostException"> /// If Win32's PeekConsoleInput fails /// </exception> internal static int PeekConsoleInput ( ConsoleHandle consoleHandle, ref INPUT_RECORD[] buffer ) { Dbg.Assert(!consoleHandle.IsInvalid, "ConsoleHandle is not valid"); Dbg.Assert(!consoleHandle.IsClosed, "ConsoleHandle is closed"); DWORD recordsRead; bool result = NativeMethods.PeekConsoleInput( consoleHandle.DangerousGetHandle(), buffer, (DWORD)buffer.Length, out recordsRead); if (result == false) { int err = Marshal.GetLastWin32Error(); HostException e = CreateHostException(err, "PeekConsoleInput", ErrorCategory.ReadError, ConsoleControlStrings.PeekConsoleInputExceptionTemplate); throw e; } return (int)recordsRead; }
public static extern bool PeekConsoleInput( IntPtr hConsoleInput, ref INPUT_RECORD lpBuffer, uint nLength, out uint lpNumberOfEventsRead );
public UserInputEventArgs(INPUT_RECORD inputRecord) { this.inputRecord = inputRecord; }
public static extern bool ReadConsoleInput(ConsoleHandle hConsoleInput, ref INPUT_RECORD lpBuffer, uint nLenght, ref uint lpNumberOfEventsRead);
public async Task InputEvents_AllKindsOfEvents_EventsFired() { var keyRecord = new INPUT_RECORD { EventType = InputEventType.Key, Event = new INPUT_RECORD.EVENTUNION { KeyEvent = new KEY_EVENT_RECORD { ControlKeys = ControlKeyStates.LEFT_ALT_PRESSED, KeyDown = 12, RepeatCount = 23, UnicodeChar = 'x', VirtualKeyCode = VirtualKey.Accept, VirtualScanCode = 42 } } }; var mouseRecord = new INPUT_RECORD { EventType = InputEventType.Mouse, Event = new INPUT_RECORD.EVENTUNION { MouseEvent = new MOUSE_EVENT_RECORD { ControlKeys = ControlKeyStates.LEFT_ALT_PRESSED, EventFlags = MouseEventFlags.DoubleClick, ButtonState = MouseButtonStates.FourthButtonPressed, MousePosition = new COORD(23, 42), Scroll = 17 } } }; var sizeRecord = new INPUT_RECORD { EventType = InputEventType.WindowBufferSize, Event = new INPUT_RECORD.EVENTUNION { SizeEvent = new WINDOW_BUFFER_SIZE_RECORD { Size = new COORD(23, 42) } } }; var menuRecord = new INPUT_RECORD { EventType = InputEventType.Menu, Event = new INPUT_RECORD.EVENTUNION { MenuEvent = new MENU_EVENT_RECORD { CommandId = 123 } } }; var focusRecord = new INPUT_RECORD { EventType = InputEventType.Focus, Event = new INPUT_RECORD.EVENTUNION { FocusEvent = new FOCUS_EVENT_RECORD { SetFocus = 123 } } }; var records = new[] { keyRecord, mouseRecord, sizeRecord, menuRecord, focusRecord }; var keyTcs = new TaskCompletionSource <int>(); var mouseTcs = new TaskCompletionSource <int>(); var sizeTcs = new TaskCompletionSource <int>(); var menuTcs = new TaskCompletionSource <int>(); var focusTcs = new TaskCompletionSource <int>(); using var api = new StubbedNativeCalls(); api.ReadConsoleInputConsoleInputHandleInt32 = (handle, size) => { handle.Should().Be(api.StdIn); return(records); }; api.GetConsoleScreenBufferInfoConsoleOutputHandle = handle => { handle.Should().Be(api.ScreenHandle); return(new CONSOLE_SCREEN_BUFFER_INFOEX { Window = new SMALL_RECT(1, 2, 4, 6), BufferSize = sizeRecord.Event.SizeEvent.Size }); }; using var sut = new ConControls.ConsoleApi.ConsoleController(api); sut.KeyEvent += (sender, e) => { e.KeyDown.Should().Be(keyRecord.Event.KeyEvent.KeyDown != 0); e.UnicodeChar.Should().Be(keyRecord.Event.KeyEvent.UnicodeChar); e.RepeatCount.Should().Be(keyRecord.Event.KeyEvent.RepeatCount); e.VirtualKeyCode.Should().Be(keyRecord.Event.KeyEvent.VirtualKeyCode); e.VirtualScanCode.Should().Be(keyRecord.Event.KeyEvent.VirtualScanCode); e.ControlKeys.Should().Be(keyRecord.Event.KeyEvent.ControlKeys); keyTcs.SetResult(0); }; sut.MouseEvent += (sender, e) => { e.ButtonState.Should().Be(mouseRecord.Event.MouseEvent.ButtonState); e.EventFlags.Should().Be(mouseRecord.Event.MouseEvent.EventFlags); e.MousePosition.X.Should().Be(mouseRecord.Event.MouseEvent.MousePosition.X); e.MousePosition.Y.Should().Be(mouseRecord.Event.MouseEvent.MousePosition.Y); e.Scroll.Should().Be(mouseRecord.Event.MouseEvent.Scroll); e.ControlKeys.Should().Be(mouseRecord.Event.MouseEvent.ControlKeys); mouseTcs.SetResult(0); }; sut.SizeEvent += (sender, e) => { if (e.WindowArea == new Rectangle(1, 2, 3, 4) && e.BufferSize.Width == sizeRecord.Event.SizeEvent.Size.X && e.BufferSize.Height == sizeRecord.Event.SizeEvent.Size.Y) { sizeTcs.TrySetResult(0); } }; sut.MenuEvent += (sender, e) => { e.CommandId.Should().Be(menuRecord.Event.MenuEvent.CommandId); menuTcs.SetResult(0); }; sut.FocusEvent += (sender, e) => { e.SetFocus.Should().Be(focusRecord.Event.FocusEvent.SetFocus != 0); focusTcs.SetResult(0); }; var allTasks = Task.WhenAll(new Task[] { keyTcs.Task, mouseTcs.Task, sizeTcs.Task, menuTcs.Task, focusTcs.Task }); api.StdInEvent.Set(); //await allTasks; (await Task.WhenAny(allTasks, Task.Delay(2000))) .Should() .Be(allTasks, "events should be processed in less than 2 seconds!"); }
internal static bool AddToConsoleInputBuffer(string str, bool newLine) { uint num3; IntPtr stdHandle = GetStdHandle(-10); if (stdHandle == IntPtr.Zero) { return false; } uint length = (uint) str.Length; INPUT_RECORD[] lpBuffer = new INPUT_RECORD[length + (newLine ? ((long) 1) : ((long) 0))]; for (int i = 0; i < length; i++) { INPUT_RECORD.SetInputRecord(ref lpBuffer[i], str[i]); } if (!WriteConsoleInput(stdHandle, lpBuffer, length, out num3) || (num3 != length)) { return false; } if (newLine) { INPUT_RECORD[] input_recordArray2 = new INPUT_RECORD[1]; INPUT_RECORD.SetInputRecord(ref input_recordArray2[0], '\r'); num3 = 0; if (!WriteConsoleInput(stdHandle, input_recordArray2, 1, out num3)) { return false; } } return true; }
// The main function of this class. public void PasswordInput(ref string refPasswordToBuild, int iMaxNumberOfCharactersSet) { INPUT_RECORD[] irInBuf = new INPUT_RECORD[128]; // Define an array of 128 INPUT_RECORD structs. uint cNumRead = 0; bool bContinueLoop = true; // Used to indicate whether to continue our ReadConsoleInput() loop. // Reset character counter. iCounter = 0; // Initialize hStdin. if (hStdin == (IntPtr)0) { hStdin = GetStdHandle(Constants.STD_INPUT_HANDLE); if (hStdin == Constants.INVALID_HANDLE_VALUE) { return; } } // Initialize hStdout. if (hStdout == (IntPtr)0) { hStdout = GetStdHandle(Constants.STD_OUTPUT_HANDLE); if (hStdout == Constants.INVALID_HANDLE_VALUE) { return; } } // Retrieve the current console mode. if (GetConsoleMode(hStdin, ref dwSaveOldMode) == false) { return; } // Set the current console mode to enable window input and mouse input. // This is not necessary for our password processing application. // This is set only for demonstration purposes. // // By setting ENABLE_WINDOW_INPUT into the console mode, user interactions // that change the size of the console screen buffer are reported in the // console's input buffer. Information about this event can be read from // the input buffer by our application using the ReadConsoleInput function. // // By setting ENABLE_MOUSE_INPUT into the console mode, if the mouse pointer // is within the borders of the console window and the window has the // keyboard focus, mouse events generated by mouse movement and button presses // are placed in the input buffer. Information about this event can be read from // the input buffer by our application using the ReadConsoleInput function. dwMode = Constants.ENABLE_WINDOW_INPUT | Constants.ENABLE_MOUSE_INPUT; if (SetConsoleMode(hStdin, dwMode) == false) { return; } // To safeguard against invalid values, we stipulate that only if iMaxNumberOfCharactersSet // is greater than zero do we set MaxNumberOfCharacters equal to it. // Otherwise, MaxNumberOfCharacters is set to 20 by default. // An alternative to setting MaxNumberOfCharacters to a default value is to throw an exception. if (iMaxNumberOfCharactersSet > 0) { MaxNumberOfCharacters = iMaxNumberOfCharactersSet; } else { // We could throw an exception here if we want to. MaxNumberOfCharacters = 20; } // Main loop to collect characters typed into the console. while (bContinueLoop == true) { if ( ReadConsoleInput ( hStdin, // input buffer handle irInBuf, // buffer to read into 128, // size of read buffer out cNumRead // number of records read ) == true ) { // Dispatch the events to the appropriate handler. for (uint i = 0; i < cNumRead; i++) { // Lookup the hashtable for the appropriate handler function... courtesy of Derek Kiong ! ConsoleInputEvent cie_handler = (ConsoleInputEvent)htCodeLookup[(object)(irInBuf[i].EventType)]; // Note well that htCodeLookup may not have the handler for the current event, // so check first for a null value in cie_handler. if (cie_handler != null) { // Invoke the handler. bContinueLoop = cie_handler(irInBuf[i], ref refPasswordToBuild); } } } } // Restore the previous mode before we exit. SetConsoleMode(hStdin, dwSaveOldMode); return; }
internal static extern bool WriteConsoleInput(IntPtr hConsoleInput, INPUT_RECORD[] lpBuffer, uint nLength, out uint lpNumberOfEventsWritten);
internal static extern bool PeekConsoleInput( IntPtr hConsoleInput, out INPUT_RECORD buffer, int numInputRecords_UseOne, out int numEventsRead);
internal static extern bool ReadConsoleInput( IntPtr hConsoleInput, ref INPUT_RECORD lpBuffer, uint nLength, ref uint lpNumberOfEventsRead );
/// <summary> /// Sets the necessary fields of <paramref name="inputRecord"/> for a KeyDown event for the <paramref name="character"/> /// </summary> /// <param name="inputRecord">Input record to be set.</param> /// <param name="character">Character to set the record with.</param> internal static void SetInputRecord(ref INPUT_RECORD inputRecord, char character) { inputRecord.EventType = INPUT_RECORD.KEY_EVENT; inputRecord.KeyEvent.bKeyDown = true; inputRecord.KeyEvent.UnicodeChar = character; }
/// <summary> /// Sets the necessary fields of <paramref name="inputRecord"/> for a KeyDown event for the <paramref name="character"/> /// </summary> /// <param name="inputRecord">input record to be set</param> /// <param name="character">character to set the record with</param> internal static void SetInputRecord(ref INPUT_RECORD inputRecord, char character) { inputRecord.EventType = INPUT_RECORD.KEY_EVENT; inputRecord.KeyEvent.bKeyDown = true; inputRecord.KeyEvent.UnicodeChar = character; }