private static void ScrollBuffer(int lines) { var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output); var scrollRectangle = new SMALL_RECT { Top = (short) lines, Left = 0, Bottom = (short) (Console.BufferHeight - 1), Right = (short)Console.BufferWidth }; var destinationOrigin = new COORD {X = 0, Y = 0}; var fillChar = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor); NativeMethods.ScrollConsoleScreenBuffer(handle, ref scrollRectangle, IntPtr.Zero, destinationOrigin, ref fillChar); }
private int ConvertLineAndColumnToOffset(COORD coord) { int offset; int x = _initialX; int y = _initialY + Options.ExtraPromptLineCount; int bufferWidth = Console.BufferWidth; var continuationPromptLength = Options.ContinuationPrompt.Length; for (offset = 0; offset < _buffer.Length; offset++) { // If we are on the correct line, return when we find // the correct column if (coord.Y == y && coord.X <= x) { return(offset); } char c = _buffer[offset]; if (c == '\n') { // If we are about to move off of the correct line, // the line was shorter than the column we wanted so return. if (coord.Y == y) { return(offset); } y += 1; x = continuationPromptLength; } else { x += char.IsControl(c) ? 2 : 1; // Wrap? No prompt when wrapping if (x >= bufferWidth) { x -= bufferWidth; y += 1; } } } // Return -1 if y is out of range, otherwise the last line was shorter // than we wanted, but still in range so just return the last offset.B return((coord.Y == y) ? offset : -1); }
private static CHAR_INFO[] ReadBufferLines(int top, int count) { var result = new CHAR_INFO[Console.BufferWidth * count]; var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output); var readBufferSize = new COORD { X = (short)Console.BufferWidth, Y = (short)count}; var readBufferCoord = new COORD {X = 0, Y = 0}; var readRegion = new SMALL_RECT { Top = (short)top, Left = 0, Bottom = (short)(top + count), Right = (short)(Console.BufferWidth - 1) }; NativeMethods.ReadConsoleOutput(handle, result, readBufferSize, readBufferCoord, ref readRegion); return result; }
private static void WriteBufferLines(CHAR_INFO[] buffer, ref int top) { var handle = NativeMethods.GetStdHandle((uint)StandardHandleId.Output); int bufferWidth = Console.BufferWidth; int bufferLineCount = buffer.Length / bufferWidth; if ((top + bufferLineCount) > Console.BufferHeight) { var scrollCount = (top + bufferLineCount) - Console.BufferHeight; ScrollBuffer(scrollCount); top -= scrollCount; } var bufferSize = new COORD { X = (short)bufferWidth, Y = (short)bufferLineCount }; var bufferCoord = new COORD { X = 0, Y = 0 }; var bottom = top + bufferLineCount - 1; var writeRegion = new SMALL_RECT { Top = (short)top, Left = 0, Bottom = (short)bottom, Right = (short)(bufferWidth - 1) }; NativeMethods.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion); // Now make sure the bottom line is visible if (bottom >= (Console.WindowTop + Console.WindowHeight)) { Console.CursorTop = bottom; } }
private static void ScrollBuffer(int lines) { var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output); var scrollRectangle = new SMALL_RECT { Top = (short) lines, Left = 0, Bottom = (short) (lines + Console.BufferHeight - 1), Right = (short)Console.BufferWidth }; var destinationOrigin = new COORD {X = 0, Y = 0}; var fillChar = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor); NativeMethods.ScrollConsoleScreenBuffer(handle, ref scrollRectangle, IntPtr.Zero, destinationOrigin, ref fillChar); }
public static extern bool WriteConsoleOutput(IntPtr consoleOutput, CHAR_INFO[] buffer, COORD bufferSize, COORD bufferCoord, ref SMALL_RECT writeRegion);
public static extern bool ScrollConsoleScreenBuffer(IntPtr hConsoleOutput, ref SMALL_RECT lpScrollRectangle, ref SMALL_RECT lpClipRectangle, COORD dwDestinationOrigin, ref CHAR_INFO lpFill);
public static extern bool ReadConsoleOutput(IntPtr consoleOutput, [Out] CHAR_INFO[] buffer, COORD bufferSize, COORD bufferCoord, ref SMALL_RECT readRegion);
static void Box(List<string> list) { int internalBoxWidth = Math.Min(Console.BufferWidth - 2, list.Max(e => e.Length)); int boxWidth = internalBoxWidth + 2; int internalBoxHeight = list.Count; int boxHeight = internalBoxHeight + 2; var buffer = new CHAR_INFO[boxWidth * boxHeight]; buffer[0].UnicodeChar = '+'; buffer[boxWidth - 1].UnicodeChar = '+'; for (int i = 1; i < boxWidth - 1; i++) { buffer[i].UnicodeChar = '-'; } for (int i = 0; i < list.Count; i++) { int rowStart = (i + 1) * boxWidth; buffer[rowStart++].UnicodeChar = '|'; buffer[rowStart + internalBoxWidth].UnicodeChar = '|'; string s = list[i]; int j; for (j = 0; j < s.Length; j++) { buffer[rowStart + j].UnicodeChar = s[j]; } for (; j < internalBoxWidth; j++) { buffer[rowStart + j].UnicodeChar = ' '; } } int lastRowStart = (boxHeight - 1) * boxWidth; buffer[lastRowStart].UnicodeChar = '+'; for (int i = 1; i < boxWidth - 1; i++) { buffer[i + lastRowStart].UnicodeChar = '-'; } buffer[lastRowStart + boxWidth - 1].UnicodeChar = '+'; for (int i = 0; i < buffer.Length; i++) { buffer[i].Attributes = (ushort)ConsoleColor.Blue | ((ushort)(ConsoleColor.DarkGreen) << 4); if (i % 2 != 0) { buffer[i].Attributes |= 0xfff0; } } var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output); var bufferSize = new COORD {X = (short)boxWidth, Y = (short)boxHeight}; var bufferCoord = new COORD {X = 0, Y = 0}; var writeRegion = new SMALL_RECT { Top = 1, Left = 1, Bottom = (short)(1 + boxHeight), Right = (short)(1 + boxWidth)}; Console.WriteLine("some random stuff"); Console.WriteLine("and more some random stuff"); Console.WriteLine("lorem ipsum blah blah"); Console.ReadKey(); var saveBuffer = new CHAR_INFO[buffer.Length]; NativeMethods.ReadConsoleOutput(handle, saveBuffer, bufferSize, bufferCoord, ref writeRegion); unsafe { fixed (CHAR_INFO* p = &buffer[0]) fixed (CHAR_INFO* sp = &saveBuffer[0]) { NativeMethods.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion); Console.ReadKey(); NativeMethods.WriteConsoleOutput(handle, saveBuffer, bufferSize, bufferCoord, ref writeRegion); } } Console.ReadKey(); }
private int ConvertLineAndColumnToOffset(COORD coord) { int offset; int x = _initialX; int y = _initialY + Options.ExtraPromptLineCount; int bufferWidth = Console.BufferWidth; var continuationPromptLength = Options.ContinuationPrompt.Length; for (offset = 0; offset < _buffer.Length; offset++) { // If we are on the correct line, return when we find // the correct column if (coord.Y == y && coord.X <= x) { return offset; } char c = _buffer[offset]; if (c == '\n') { // If we are about to move off of the correct line, // the line was shorter than the column we wanted so return. if (coord.Y == y) { return offset; } y += 1; x = continuationPromptLength; } else { x += char.IsControl(c) ? 2 : 1; // Wrap? No prompt when wrapping if (x >= bufferWidth) { x -= bufferWidth; y += 1; } } } // Return -1 if y is out of range, otherwise the last line was shorter // than we wanted, but still in range so just return the last offset.B return (coord.Y == y) ? offset : -1; }
private static void WriteBufferLines(CHAR_INFO[] buffer, ref int top) { var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output); int bufferWidth = Console.BufferWidth; int bufferLineCount = buffer.Length / bufferWidth; if ((top + bufferLineCount) > Console.BufferHeight) { var scrollCount = (top + bufferLineCount) - Console.BufferHeight; ScrollBuffer(scrollCount); top -= scrollCount; } var bufferSize = new COORD { X = (short) bufferWidth, Y = (short) bufferLineCount }; var bufferCoord = new COORD {X = 0, Y = 0}; var bottom = top + bufferLineCount - 1; var writeRegion = new SMALL_RECT { Top = (short) top, Left = 0, Bottom = (short) bottom, Right = (short) (bufferWidth - 1) }; NativeMethods.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion); // Now make sure the bottom line is visible if (bottom >= (Console.WindowTop + Console.WindowHeight)) { Console.CursorTop = bottom; } }
private static void SetPrompt(string prompt) { if (string.IsNullOrEmpty(prompt)) return; var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output); var lineCount = 1 + prompt.Count(c => c == '\n'); if (lineCount > 1) { var options = new SetPSReadlineOption {ExtraPromptLineCount = lineCount - 1}; PSConsoleReadLine.SetOptions(options); } int bufferWidth = Console.BufferWidth; var consoleBuffer = new CHAR_INFO[lineCount * bufferWidth]; int j = 0; for (int i = 0; i < prompt.Length; i++, j++) { if (prompt[i] == '\n') { for (; j % Console.BufferWidth != 0; j++) { consoleBuffer[j] = new CHAR_INFO(' ', Console.ForegroundColor, Console.BackgroundColor); } Console.CursorTop += 1; Console.CursorLeft = 0; j -= 1; // We don't actually write the newline } else { consoleBuffer[j] = new CHAR_INFO(prompt[i], Console.ForegroundColor, Console.BackgroundColor); Console.CursorLeft += 1; } } var bufferSize = new COORD { X = (short) bufferWidth, Y = (short) lineCount }; var bufferCoord = new COORD {X = 0, Y = 0}; var writeRegion = new SMALL_RECT { Top = 0, Left = 0, Bottom = (short) (lineCount - 1), Right = (short) bufferWidth }; NativeMethods.WriteConsoleOutput(handle, consoleBuffer, bufferSize, bufferCoord, ref writeRegion); }
private static void WriteBufferLines(CHAR_INFO[] buffer, ref int top) { var handle = NativeMethods.GetStdHandle((uint) StandardHandleId.Output); int bufferWidth = Console.BufferWidth; int bufferLineCount = buffer.Length / bufferWidth; if ((top + bufferLineCount) > Console.BufferHeight) { var scrollCount = (top + bufferLineCount) - Console.BufferHeight; ScrollBuffer(scrollCount); top -= scrollCount; } var bufferSize = new COORD { X = (short) bufferWidth, Y = (short) bufferLineCount }; var bufferCoord = new COORD {X = 0, Y = 0}; var writeRegion = new SMALL_RECT { Top = (short) top, Left = 0, Bottom = (short) (top + bufferLineCount - 1), Right = (short) bufferWidth }; NativeMethods.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion); }
public static extern bool ScrollConsoleScreenBuffer(IntPtr hConsoleOutput, ref SMALL_RECT lpScrollRectangle, IntPtr lpClipRectangle, COORD dwDestinationOrigin, ref CHAR_INFO lpFill);