internal static extern bool ReadConsole ( IntPtr consoleInput, StringBuilder buffer, uint numberOfCharsToRead, out uint numberOfCharsRead, ref CONSOLE_READCONSOLE_CONTROL controlData );
/// <summary> /// Reads character input from the console input buffer and removes it from the buffer. /// </summary> /// <param name="hConsoleInput">A handle to the console input buffer. The handle must have the <see cref="BUFFER_ACCESS_MODE.GENERIC_READ"/> access right.</param> /// <param name="lpBuffer">A pointer to a buffer that receives the data read from the console input buffer.</param> /// <param name="nNumberOfCharsToRead">The number of characters to be read.</param> /// <param name="lpNumberOfCharsRead">A pointer to a variable that receives the number of characters actually read.</param> /// <param name="pInputControl"> /// A <see cref="CONSOLE_READCONSOLE_CONTROL"/> structure that contains a control character to signal the end of the read operation. This parameter can be <see langword="null"/>. /// This parameter requires Unicode input by default. For ANSI mode, set this parameter to see langword="null"/>. /// </param> /// <returns>If the function succeeds, returns TRUE, otherwise, retun FALSE.</returns> [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadConsole([In] IntPtr hConsoleInput, [Out] StringBuilder lpBuffer, [In] uint nNumberOfCharsToRead, [Out] out uint lpNumberOfCharsRead, [In, Optional] CONSOLE_READCONSOLE_CONTROL pInputControl);
/// <summary> /// /// Reads input from the console device according to the mode in effect (see GetMode, SetMode) /// /// </summary> /// <param name="consoleHandle"></param> /// /// Handle to the console device returned by GetInputHandle /// /// <param name="initialContent"> /// /// Initial contents of the edit buffer, if any. charactersToRead should be at least as large as the length of this string. /// /// </param> /// <param name="charactersToRead"> /// /// Number of characters to read from the device. /// /// </param> /// <param name="endOnTab"> /// /// true to allow the user to terminate input by hitting the tab or shift-tab key, in addition to the enter key /// /// </param> /// <param name="keyState"> /// /// bit mask indicating the state of the control/shift keys at the point input was terminated. /// /// </param> /// <returns></returns> /// <exception cref="HostException"> /// /// If Win32's ReadConsole fails /// /// </exception> internal static string ReadConsole(ConsoleHandle consoleHandle, string initialContent, int charactersToRead, bool endOnTab, out uint keyState) { Dbg.Assert(!consoleHandle.IsInvalid, "ConsoleHandle is not valid"); Dbg.Assert(!consoleHandle.IsClosed, "ConsoleHandle is closed"); Dbg.Assert(initialContent != null, "if no initial content is desired, pass String.Empty"); keyState = 0; CONSOLE_READCONSOLE_CONTROL control = new CONSOLE_READCONSOLE_CONTROL(); control.nLength = (ULONG)Marshal.SizeOf(control); control.nInitialChars = (ULONG)initialContent.Length; control.dwControlKeyState = 0; if (endOnTab) { const int TAB = 0x9; control.dwCtrlWakeupMask = (1 << TAB); } DWORD charsReadUnused = 0; StringBuilder buffer = new StringBuilder(initialContent, charactersToRead); bool result = NativeMethods.ReadConsole( consoleHandle.DangerousGetHandle(), buffer, (DWORD)charactersToRead, out charsReadUnused, ref control); keyState = control.dwControlKeyState; if (result == false) { int err = Marshal.GetLastWin32Error(); HostException e = CreateHostException(err, "ReadConsole", ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleExceptionTemplate); throw e; } if (charsReadUnused > (uint)buffer.Length) charsReadUnused = (uint)buffer.Length; return buffer.ToString(0, (int)charsReadUnused); }
internal static extern bool ReadConsole ( NakedWin32Handle consoleInput, StringBuilder buffer, DWORD numberOfCharsToRead, out DWORD numberOfCharsRead, // This magical parameter is not documented, but is the secret to tab-completion. ref CONSOLE_READCONSOLE_CONTROL controlData );