public static unsafe void SetWindowPosition(int left, int top) { // Get the size of the current console window Interop.mincore.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(); Interop.mincore.SMALL_RECT srWindow = csbi.srWindow; // Check for arithmetic underflows & overflows. int newRight = left + srWindow.Right - srWindow.Left + 1; if (left < 0 || newRight > csbi.dwSize.X || newRight < 0) { throw new ArgumentOutOfRangeException("left", left, SR.ArgumentOutOfRange_ConsoleWindowPos); } int newBottom = top + srWindow.Bottom - srWindow.Top + 1; if (top < 0 || newBottom > csbi.dwSize.Y || newBottom < 0) { throw new ArgumentOutOfRangeException("top", top, SR.ArgumentOutOfRange_ConsoleWindowPos); } // Preserve the size, but move the position. srWindow.Bottom -= (short)(srWindow.Top - top); srWindow.Right -= (short)(srWindow.Left - left); srWindow.Left = (short)left; srWindow.Top = (short)top; bool r = Interop.mincore.SetConsoleWindowInfo(OutputHandle, true, &srWindow); if (!r) { throw Win32Marshal.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); } }
[System.Security.SecuritySafeCritical] // auto-generated public static void SetBufferSize(int width, int height) { // Ensure the new size is not smaller than the console window Interop.mincore.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(); Interop.mincore.SMALL_RECT srWindow = csbi.srWindow; if (width < srWindow.Right + 1 || width >= short.MaxValue) { throw new ArgumentOutOfRangeException("width", width, SR.ArgumentOutOfRange_ConsoleBufferLessThanWindowSize); } if (height < srWindow.Bottom + 1 || height >= short.MaxValue) { throw new ArgumentOutOfRangeException("height", height, SR.ArgumentOutOfRange_ConsoleBufferLessThanWindowSize); } Interop.mincore.COORD size = new Interop.mincore.COORD(); size.X = (short)width; size.Y = (short)height; if (!Interop.mincore.SetConsoleScreenBufferSize(OutputHandle, size)) { throw Win32Marshal.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); } }
public unsafe static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) { if (sourceForeColor < ConsoleColor.Black || sourceForeColor > ConsoleColor.White) throw new ArgumentException(SR.Arg_InvalidConsoleColor, nameof(sourceForeColor)); if (sourceBackColor < ConsoleColor.Black || sourceBackColor > ConsoleColor.White) throw new ArgumentException(SR.Arg_InvalidConsoleColor, nameof(sourceBackColor)); Contract.EndContractBlock(); Interop.mincore.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(); Interop.mincore.COORD bufferSize = csbi.dwSize; if (sourceLeft < 0 || sourceLeft > bufferSize.X) throw new ArgumentOutOfRangeException(nameof(sourceLeft), sourceLeft, SR.ArgumentOutOfRange_ConsoleBufferBoundaries); if (sourceTop < 0 || sourceTop > bufferSize.Y) throw new ArgumentOutOfRangeException(nameof(sourceTop), sourceTop, SR.ArgumentOutOfRange_ConsoleBufferBoundaries); if (sourceWidth < 0 || sourceWidth > bufferSize.X - sourceLeft) throw new ArgumentOutOfRangeException(nameof(sourceWidth), sourceWidth, SR.ArgumentOutOfRange_ConsoleBufferBoundaries); if (sourceHeight < 0 || sourceTop > bufferSize.Y - sourceHeight) throw new ArgumentOutOfRangeException(nameof(sourceHeight), sourceHeight, SR.ArgumentOutOfRange_ConsoleBufferBoundaries); // Note: if the target range is partially in and partially out // of the buffer, then we let the OS clip it for us. if (targetLeft < 0 || targetLeft > bufferSize.X) throw new ArgumentOutOfRangeException(nameof(targetLeft), targetLeft, SR.ArgumentOutOfRange_ConsoleBufferBoundaries); if (targetTop < 0 || targetTop > bufferSize.Y) throw new ArgumentOutOfRangeException(nameof(targetTop), targetTop, SR.ArgumentOutOfRange_ConsoleBufferBoundaries); // If we're not doing any work, bail out now (Windows will return // an error otherwise) if (sourceWidth == 0 || sourceHeight == 0) return; // Read data from the original location, blank it out, then write // it to the new location. This will handle overlapping source and // destination regions correctly. // Read the old data Interop.mincore.CHAR_INFO[] data = new Interop.mincore.CHAR_INFO[sourceWidth * sourceHeight]; bufferSize.X = (short)sourceWidth; bufferSize.Y = (short)sourceHeight; Interop.mincore.COORD bufferCoord = new Interop.mincore.COORD(); Interop.mincore.SMALL_RECT readRegion = new Interop.mincore.SMALL_RECT(); readRegion.Left = (short)sourceLeft; readRegion.Right = (short)(sourceLeft + sourceWidth - 1); readRegion.Top = (short)sourceTop; readRegion.Bottom = (short)(sourceTop + sourceHeight - 1); bool r; fixed (Interop.mincore.CHAR_INFO* pCharInfo = data) r = Interop.mincore.ReadConsoleOutput(OutputHandle, pCharInfo, bufferSize, bufferCoord, ref readRegion); if (!r) throw Win32Marshal.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); // Overwrite old section Interop.mincore.COORD writeCoord = new Interop.mincore.COORD(); writeCoord.X = (short)sourceLeft; Interop.mincore.Color c = ConsoleColorToColorAttribute(sourceBackColor, true); c |= ConsoleColorToColorAttribute(sourceForeColor, false); short attr = (short)c; int numWritten; for (int i = sourceTop; i < sourceTop + sourceHeight; i++) { writeCoord.Y = (short)i; r = Interop.mincore.FillConsoleOutputCharacter(OutputHandle, sourceChar, sourceWidth, writeCoord, out numWritten); Debug.Assert(numWritten == sourceWidth, "FillConsoleOutputCharacter wrote the wrong number of chars!"); if (!r) throw Win32Marshal.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); r = Interop.mincore.FillConsoleOutputAttribute(OutputHandle, attr, sourceWidth, writeCoord, out numWritten); if (!r) throw Win32Marshal.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); } // Write text to new location Interop.mincore.SMALL_RECT writeRegion = new Interop.mincore.SMALL_RECT(); writeRegion.Left = (short)targetLeft; writeRegion.Right = (short)(targetLeft + sourceWidth); writeRegion.Top = (short)targetTop; writeRegion.Bottom = (short)(targetTop + sourceHeight); fixed (Interop.mincore.CHAR_INFO* pCharInfo = data) Interop.mincore.WriteConsoleOutput(OutputHandle, pCharInfo, bufferSize, bufferCoord, ref writeRegion); }
public static unsafe void SetWindowSize(int width, int height) { if (width <= 0) { throw new ArgumentOutOfRangeException("width", width, SR.ArgumentOutOfRange_NeedPosNum); } if (height <= 0) { throw new ArgumentOutOfRangeException("height", height, SR.ArgumentOutOfRange_NeedPosNum); } // Get the position of the current console window Interop.mincore.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(); // If the buffer is smaller than this new window size, resize the // buffer to be large enough. Include window position. bool resizeBuffer = false; Interop.mincore.COORD size = new Interop.mincore.COORD(); size.X = csbi.dwSize.X; size.Y = csbi.dwSize.Y; if (csbi.dwSize.X < csbi.srWindow.Left + width) { if (csbi.srWindow.Left >= short.MaxValue - width) { throw new ArgumentOutOfRangeException("width", SR.ArgumentOutOfRange_ConsoleWindowBufferSize); } size.X = (short)(csbi.srWindow.Left + width); resizeBuffer = true; } if (csbi.dwSize.Y < csbi.srWindow.Top + height) { if (csbi.srWindow.Top >= short.MaxValue - height) { throw new ArgumentOutOfRangeException("height", SR.ArgumentOutOfRange_ConsoleWindowBufferSize); } size.Y = (short)(csbi.srWindow.Top + height); resizeBuffer = true; } if (resizeBuffer) { if (!Interop.mincore.SetConsoleScreenBufferSize(OutputHandle, size)) { throw Win32Marshal.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); } } Interop.mincore.SMALL_RECT srWindow = csbi.srWindow; // Preserve the position, but change the size. srWindow.Bottom = (short)(srWindow.Top + height - 1); srWindow.Right = (short)(srWindow.Left + width - 1); if (!Interop.mincore.SetConsoleWindowInfo(OutputHandle, true, &srWindow)) { int errorCode = Marshal.GetLastWin32Error(); // If we resized the buffer, un-resize it. if (resizeBuffer) { Interop.mincore.SetConsoleScreenBufferSize(OutputHandle, csbi.dwSize); } // Try to give a better error message here Interop.mincore.COORD bounds = Interop.mincore.GetLargestConsoleWindowSize(OutputHandle); if (width > bounds.X) { throw new ArgumentOutOfRangeException("width", width, SR.Format(SR.ArgumentOutOfRange_ConsoleWindowSize_Size, bounds.X)); } if (height > bounds.Y) { throw new ArgumentOutOfRangeException("height", height, SR.Format(SR.ArgumentOutOfRange_ConsoleWindowSize_Size, bounds.Y)); } throw Win32Marshal.GetExceptionForWin32Error(errorCode); } }