/// <summary> /// Reads the input from the input buffer. /// </summary> public ReadRef ReadInput(ReadOptions options) { var handle = GetInputBuffer(); uint read = 0; var readRef = new ReadRef(); StringBuilder inputBuffer = new StringBuilder(options.InitialContent); int currentLength = 0; //Save current mode. uint currentMode = 0; ConsoleHostNativeMethods.GetConsoleMode(handle.DangerousGetHandle(), out currentMode); ConsoleModes newMode = (ConsoleModes)currentMode & ~ConsoleModes.WindowInput & ~ConsoleModes.MouseInput & ~ConsoleModes.ProcessedInput; ConsoleHostNativeMethods.SetConsoleMode(handle.DangerousGetHandle(), (uint)newMode); while (true) { var inputs = DotConsoleNative.ReadConsoleKeys(handle, 1, out read); if (inputs != null && inputs.Length > 0) { if (read == 1) { var input = inputs[0]; if (input.KeyEvent.repeatCount == 0) { //for some bizzare reson this can return a key or record //but repeat count is zero so we should not process it in any way. //This can happen if we're after mouse inputs such as mouse move. continue; } if (input.KeyEvent.keyDown == true) { if (input.EventType == (ushort)KeyEventType.KEY_EVENT) { if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Return) { break; } if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Left) { //set cursor position. //Should we use the cursor position from renderrer ? or perhaps use //the one from the output buffer of the console that we're using ? var currentCursorPosition = parent.GetCursorPosition(); currentCursorPosition.X -= 1; parent.SetCursorPosition(currentCursorPosition); parent.SetBufferPosition(currentCursorPosition); } else if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Right) { //set cursor position. //Should we use the cursor position from renderrer ? or perhaps use //the one from the output buffer of the console that we're using ? var currentCursorPosition = parent.GetCursorPosition(); currentCursorPosition.X += 1; parent.SetCursorPosition(currentCursorPosition); parent.SetBufferPosition(currentCursorPosition); } else if (input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Back) { var currentCursorPosition = parent.GetCursorPosition(); currentCursorPosition.X -= 1; inputBuffer.Remove(inputBuffer.Length - 1, 1); if (options.NoEcho == false) { parent.AlterLine(string.Empty, currentCursorPosition.Y, currentCursorPosition.X, 1, options.BackgroundColor, options.ForegroundColor); } parent.SetCursorPosition(currentCursorPosition); parent.SetBufferPosition(currentCursorPosition); } else { if (options.StopOnUpArrow && input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Up) { readRef.IsUpArrow = true; break; } else if (options.StopOnDownArrow && input.KeyEvent.virtualKeyCode == (ushort)VirtualInputCode.Down) { readRef.IsDownArrow = true; break; } if (options.StopChars != null) { if (options.StopChars.Contains(input.KeyEvent.unicodeChar)) { readRef.StopChar = (input.KeyEvent.unicodeChar); break; } } currentLength++; inputBuffer.Append(input.KeyEvent.unicodeChar); if (options.NoEcho == false) { parent.Write(input.KeyEvent.unicodeChar.ToString(), options.BackgroundColor, options.ForegroundColor, false); } //Maximum allowed chars read, break the input loop. if (options.ReadLength.HasValue && currentLength >= options.ReadLength) { break; } } } } } } } //Restore saved mode. ConsoleHostNativeMethods.SetConsoleMode(handle.DangerousGetHandle(), currentMode); readRef.ReadInput = inputBuffer.ToString(); return(readRef); }