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(Environment.GetResourceString("Arg_InvalidConsoleColor"), "sourceForeColor"); if (sourceBackColor < ConsoleColor.Black || sourceBackColor > ConsoleColor.White) throw new ArgumentException(Environment.GetResourceString("Arg_InvalidConsoleColor"), "sourceBackColor"); Contract.EndContractBlock(); Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(); Win32Native.COORD bufferSize = csbi.dwSize; if (sourceLeft < 0 || sourceLeft > bufferSize.X) throw new ArgumentOutOfRangeException("sourceLeft", sourceLeft, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); if (sourceTop < 0 || sourceTop > bufferSize.Y) throw new ArgumentOutOfRangeException("sourceTop", sourceTop, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); if (sourceWidth < 0 || sourceWidth > bufferSize.X - sourceLeft) throw new ArgumentOutOfRangeException("sourceWidth", sourceWidth, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); if (sourceHeight < 0 || sourceTop > bufferSize.Y - sourceHeight) throw new ArgumentOutOfRangeException("sourceHeight", sourceHeight, Environment.GetResourceString("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("targetLeft", targetLeft, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); if (targetTop < 0 || targetTop > bufferSize.Y) throw new ArgumentOutOfRangeException("targetTop", targetTop, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); // If we're not doing any work, bail out now (Windows will return // an error otherwise) if (sourceWidth == 0 || sourceHeight == 0) return; new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand(); // 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. // See the "Reading and Writing Blocks of Characters and Attributes" // sample for help // Read the old data Win32Native.CHAR_INFO[] data = new Win32Native.CHAR_INFO[sourceWidth * sourceHeight]; bufferSize.X = (short) sourceWidth; bufferSize.Y = (short) sourceHeight; Win32Native.COORD bufferCoord = new Win32Native.COORD(); Win32Native.SMALL_RECT readRegion = new Win32Native.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(Win32Native.CHAR_INFO* pCharInfo = data) r = Win32Native.ReadConsoleOutput(ConsoleOutputHandle, pCharInfo, bufferSize, bufferCoord, ref readRegion); if (!r) __Error.WinIOError(); // Overwrite old section // I don't have a good function to blank out a rectangle. Win32Native.COORD writeCoord = new Win32Native.COORD(); writeCoord.X = (short) sourceLeft; Win32Native.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 = Win32Native.FillConsoleOutputCharacter(ConsoleOutputHandle, sourceChar, sourceWidth, writeCoord, out numWritten); Contract.Assert(numWritten == sourceWidth, "FillConsoleOutputCharacter wrote the wrong number of chars!"); if (!r) __Error.WinIOError(); r = Win32Native.FillConsoleOutputAttribute(ConsoleOutputHandle, attr, sourceWidth, writeCoord, out numWritten); if (!r) __Error.WinIOError(); } // Write text to new location Win32Native.SMALL_RECT writeRegion = new Win32Native.SMALL_RECT(); writeRegion.Left = (short) targetLeft; writeRegion.Right = (short) (targetLeft + sourceWidth); writeRegion.Top = (short) targetTop; writeRegion.Bottom = (short) (targetTop + sourceHeight); fixed(Win32Native.CHAR_INFO* pCharInfo = data) r = Win32Native.WriteConsoleOutput(ConsoleOutputHandle, pCharInfo, bufferSize, bufferCoord, ref writeRegion); }
public static unsafe 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(Environment.GetResourceString("Arg_InvalidConsoleColor"), "sourceForeColor"); } if ((sourceBackColor < ConsoleColor.Black) || (sourceBackColor > ConsoleColor.White)) { throw new ArgumentException(Environment.GetResourceString("Arg_InvalidConsoleColor"), "sourceBackColor"); } Win32Native.COORD dwSize = GetBufferInfo().dwSize; if ((sourceLeft < 0) || (sourceLeft > dwSize.X)) { throw new ArgumentOutOfRangeException("sourceLeft", sourceLeft, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); } if ((sourceTop < 0) || (sourceTop > dwSize.Y)) { throw new ArgumentOutOfRangeException("sourceTop", sourceTop, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); } if ((sourceWidth < 0) || (sourceWidth > (dwSize.X - sourceLeft))) { throw new ArgumentOutOfRangeException("sourceWidth", sourceWidth, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); } if ((sourceHeight < 0) || (sourceTop > (dwSize.Y - sourceHeight))) { throw new ArgumentOutOfRangeException("sourceHeight", sourceHeight, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); } if ((targetLeft < 0) || (targetLeft > dwSize.X)) { throw new ArgumentOutOfRangeException("targetLeft", targetLeft, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); } if ((targetTop < 0) || (targetTop > dwSize.Y)) { throw new ArgumentOutOfRangeException("targetTop", targetTop, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries")); } if ((sourceWidth != 0) && (sourceHeight != 0)) { bool flag; Win32Native.CHAR_INFO[] char_infoArray3; new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand(); Win32Native.CHAR_INFO[] char_infoArray = new Win32Native.CHAR_INFO[sourceWidth * sourceHeight]; dwSize.X = (short) sourceWidth; dwSize.Y = (short) sourceHeight; Win32Native.COORD bufferCoord = new Win32Native.COORD(); Win32Native.SMALL_RECT readRegion = new Win32Native.SMALL_RECT { Left = (short) sourceLeft, Right = (short) ((sourceLeft + sourceWidth) - 1), Top = (short) sourceTop, Bottom = (short) ((sourceTop + sourceHeight) - 1) }; fixed (Win32Native.CHAR_INFO* char_infoRef = char_infoArray) { flag = Win32Native.ReadConsoleOutput(ConsoleOutputHandle, char_infoRef, dwSize, bufferCoord, ref readRegion); } if (!flag) { __Error.WinIOError(); } Win32Native.COORD dwWriteCoord = new Win32Native.COORD { X = (short) sourceLeft }; Win32Native.Color color = (Win32Native.Color) ((short) (ConsoleColorToColorAttribute(sourceBackColor, true) | ConsoleColorToColorAttribute(sourceForeColor, false))); short wColorAttribute = (short) color; for (int i = sourceTop; i < (sourceTop + sourceHeight); i++) { int num2; dwWriteCoord.Y = (short) i; if (!Win32Native.FillConsoleOutputCharacter(ConsoleOutputHandle, sourceChar, sourceWidth, dwWriteCoord, out num2)) { __Error.WinIOError(); } if (!Win32Native.FillConsoleOutputAttribute(ConsoleOutputHandle, wColorAttribute, sourceWidth, dwWriteCoord, out num2)) { __Error.WinIOError(); } } Win32Native.SMALL_RECT writeRegion = new Win32Native.SMALL_RECT { Left = (short) targetLeft, Right = (short) (targetLeft + sourceWidth), Top = (short) targetTop, Bottom = (short) (targetTop + sourceHeight) }; if (((char_infoArray3 = char_infoArray) == null) || (char_infoArray3.Length == 0)) { char_infoRef2 = null; goto Label_02C4; } fixed (Win32Native.CHAR_INFO* char_infoRef2 = char_infoArray3) { Label_02C4: flag = Win32Native.WriteConsoleOutput(ConsoleOutputHandle, char_infoRef2, dwSize, bufferCoord, ref writeRegion); } } }