public static ConsoleKeyInfo ReadKey(bool intercept) { Win32Native.InputRecord ir; int numEventsRead = -1; bool r; if (_cachedInputRecord.eventType == Win32Native.KEY_EVENT) { // We had a previous keystroke with repeated characters. ir = _cachedInputRecord; if (_cachedInputRecord.keyEvent.repeatCount == 0) _cachedInputRecord.eventType = -1; else { _cachedInputRecord.keyEvent.repeatCount--; } // We will return one key from this method, so we decrement the // repeatCount here, leaving the cachedInputRecord in the "queue". } else { while (true) { r = Win32Native.ReadConsoleInput(ConsoleInputHandle, out ir, 1, out numEventsRead); if (!r || numEventsRead == 0) { // This will fail when stdin is redirected from a file or pipe. // We could theoretically call Console.Read here, but I // think we might do some things incorrectly then. throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConsoleReadKeyOnFile")); } short keyCode = ir.keyEvent.virtualKeyCode; // First check for non-keyboard events & discard them. Generally we tap into only KeyDown events and ignore the KeyUp events // but it is possible that we are dealing with a Alt+NumPad unicode key sequence, the final unicode char is revealed only when // the Alt key is released (i.e when the sequence is complete). To avoid noise, when the Alt key is down, we should eat up // any intermediate key strokes (from NumPad) that collectively forms the Unicode character. if (!IsKeyDownEvent(ir)) { // if (keyCode != AltVKCode) continue; } char ch = (char)ir.keyEvent.uChar; // In a Alt+NumPad unicode sequence, when the alt key is released uChar will represent the final unicode character, we need to // surface this. VirtualKeyCode for this event will be Alt from the Alt-Up key event. This is probably not the right code, // especially when we don't expose ConsoleKey.Alt, so this will end up being the hex value (0x12). VK_PACKET comes very // close to being useful and something that we could look into using for this purpose... if (ch == 0) { // Skip mod keys. if (IsModKey(ir)) continue; } // When Alt is down, it is possible that we are in the middle of a Alt+NumPad unicode sequence. // Escape any intermediate NumPad keys whether NumLock is on or not (notepad behavior) ConsoleKey key = (ConsoleKey)keyCode; if (IsAltKeyDown(ir) && ((key >= ConsoleKey.NumPad0 && key <= ConsoleKey.NumPad9) || (key == ConsoleKey.Clear) || (key == ConsoleKey.Insert) || (key >= ConsoleKey.PageUp && key <= ConsoleKey.DownArrow))) { continue; } if (ir.keyEvent.repeatCount > 1) { ir.keyEvent.repeatCount--; _cachedInputRecord = ir; } break; } } ControlKeyState state = (ControlKeyState) ir.keyEvent.controlKeyState; bool shift = (state & ControlKeyState.ShiftPressed) != 0; bool alt = (state & (ControlKeyState.LeftAltPressed | ControlKeyState.RightAltPressed)) != 0; bool control = (state & (ControlKeyState.LeftCtrlPressed | ControlKeyState.RightCtrlPressed)) != 0; ConsoleKeyInfo info = new ConsoleKeyInfo((char)ir.keyEvent.uChar, (ConsoleKey) ir.keyEvent.virtualKeyCode, shift, alt, control); if (!intercept) Console.Write(ir.keyEvent.uChar); return info; }
public static ConsoleKeyInfo ReadKey(bool intercept) { Win32Native.InputRecord record; ControlKeyState state; int numEventsRead = -1; if (_cachedInputRecord.eventType == 1) { record = _cachedInputRecord; if (_cachedInputRecord.keyEvent.repeatCount == 0) { _cachedInputRecord.eventType = -1; } else { _cachedInputRecord.keyEvent.repeatCount = (short) (_cachedInputRecord.keyEvent.repeatCount - 1); } goto Label_0109; } Label_0053: if (!Win32Native.ReadConsoleInput(ConsoleInputHandle, out record, 1, out numEventsRead) || (numEventsRead == 0)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConsoleReadKeyOnFile")); } short virtualKeyCode = record.keyEvent.virtualKeyCode; if ((!IsKeyDownEvent(record) && (virtualKeyCode != 0x12)) || ((record.keyEvent.uChar == '\0') && IsModKey(record))) { goto Label_0053; } ConsoleKey key = (ConsoleKey) virtualKeyCode; if (IsAltKeyDown(record) && (((key >= ConsoleKey.NumPad0) && (key <= ConsoleKey.NumPad9)) || (((key == ConsoleKey.Clear) || (key == ConsoleKey.Insert)) || ((key >= ConsoleKey.PageUp) && (key <= ConsoleKey.DownArrow))))) { goto Label_0053; } if (record.keyEvent.repeatCount > 1) { record.keyEvent.repeatCount = (short) (record.keyEvent.repeatCount - 1); _cachedInputRecord = record; } Label_0109: state = (ControlKeyState) record.keyEvent.controlKeyState; bool shift = (state & ControlKeyState.ShiftPressed) != 0; bool alt = (state & (ControlKeyState.LeftAltPressed | ControlKeyState.RightAltPressed)) != 0; bool control = (state & (ControlKeyState.LeftCtrlPressed | ControlKeyState.RightCtrlPressed)) != 0; ConsoleKeyInfo info = new ConsoleKeyInfo(record.keyEvent.uChar, (ConsoleKey) record.keyEvent.virtualKeyCode, shift, alt, control); if (!intercept) { Write(record.keyEvent.uChar); } return info; }
public static ConsoleKeyInfo ReadKey(bool intercept) { int num = -1; Win32Native.InputRecord cachedInputRecord; if (Console._cachedInputRecord.eventType == 1) { cachedInputRecord = Console._cachedInputRecord; if (Console._cachedInputRecord.keyEvent.repeatCount == 0) { Console._cachedInputRecord.eventType = -1; } else { Console._cachedInputRecord.keyEvent.repeatCount = Console._cachedInputRecord.keyEvent.repeatCount - 1; } } else { while (true) { bool flag = Win32Native.ReadConsoleInput(Console.ConsoleInputHandle, out cachedInputRecord, 1, out num); if (!flag || num == 0) { break; } short virtualKeyCode = cachedInputRecord.keyEvent.virtualKeyCode; if ((Console.IsKeyDownEvent(cachedInputRecord) || virtualKeyCode == 18) && (cachedInputRecord.keyEvent.uChar != '\0' || !Console.IsModKey(cachedInputRecord))) { ConsoleKey consoleKey = (ConsoleKey)virtualKeyCode; if (!Console.IsAltKeyDown(cachedInputRecord) || ((consoleKey < ConsoleKey.NumPad0 || consoleKey > ConsoleKey.NumPad9) && consoleKey != ConsoleKey.Clear && consoleKey != ConsoleKey.Insert && (consoleKey < ConsoleKey.PageUp || consoleKey > ConsoleKey.DownArrow))) { goto IL_DF; } } } throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConsoleReadKeyOnFile")); IL_DF: if (cachedInputRecord.keyEvent.repeatCount > 1) { cachedInputRecord.keyEvent.repeatCount = cachedInputRecord.keyEvent.repeatCount - 1; Console._cachedInputRecord = cachedInputRecord; } } Console.ControlKeyState controlKeyState = (Console.ControlKeyState)cachedInputRecord.keyEvent.controlKeyState; bool shift = (controlKeyState & Console.ControlKeyState.ShiftPressed) != (Console.ControlKeyState)0; bool alt = (controlKeyState & (Console.ControlKeyState.RightAltPressed | Console.ControlKeyState.LeftAltPressed)) != (Console.ControlKeyState)0; bool control = (controlKeyState & (Console.ControlKeyState.RightCtrlPressed | Console.ControlKeyState.LeftCtrlPressed)) != (Console.ControlKeyState)0; ConsoleKeyInfo result = new ConsoleKeyInfo(cachedInputRecord.keyEvent.uChar, (ConsoleKey)cachedInputRecord.keyEvent.virtualKeyCode, shift, alt, control); if (!intercept) { Console.Write(cachedInputRecord.keyEvent.uChar); } return result; }
public static ConsoleKeyInfo ReadKey(bool intercept) { Win32Native.InputRecord record; int numEventsRead = -1; if (_cachedInputRecord.eventType == 1) { record = _cachedInputRecord; if (_cachedInputRecord.keyEvent.repeatCount == 0) { _cachedInputRecord.eventType = -1; } else { _cachedInputRecord.keyEvent.repeatCount = (short) (_cachedInputRecord.keyEvent.repeatCount - 1); } } else { do { if (!Win32Native.ReadConsoleInput(ConsoleInputHandle, out record, 1, out numEventsRead) || (numEventsRead == 0)) { throw new InvalidOperationException( Environment.GetResourceString("InvalidOperation_ConsoleReadKeyOnFile")); } } while (!IsKeyDownEvent(record) || ((record.keyEvent.uChar == '\0') && IsModKey(record.keyEvent.virtualKeyCode))); if (record.keyEvent.repeatCount > 1) { record.keyEvent.repeatCount = (short) (record.keyEvent.repeatCount - 1); _cachedInputRecord = record; } } ControlKeyState controlKeyState = (ControlKeyState) record.keyEvent.controlKeyState; bool shift = (controlKeyState & ControlKeyState.ShiftPressed) != 0; bool alt = (controlKeyState & (ControlKeyState.LeftAltPressed | ControlKeyState.RightAltPressed)) != 0; bool control = (controlKeyState & (ControlKeyState.LeftCtrlPressed | ControlKeyState.RightCtrlPressed)) != 0; ConsoleKeyInfo info = new ConsoleKeyInfo(record.keyEvent.uChar, (ConsoleKey) record.keyEvent.virtualKeyCode, shift, alt, control); if (!intercept) { Write(record.keyEvent.uChar); } return info; }