Exemplo n.º 1
0
        private static void WriteConsoleOutputPlain(ConsoleHandle consoleHandle, Coordinates origin, BufferCell[,] contents)
        {
            int rows = contents.GetLength(0);
            int cols = contents.GetLength(1);

            if ((rows <= 0) || cols <= 0)
            {
                tracer.WriteLine("contents passed in has 0 rows and columns");
                return;
            }
            int bufferLimit = 2 * 1024; // Limit is 8K bytes as each CHAR_INFO takes 4 bytes

            COORD bufferCoord;

            bufferCoord.X = 0;
            bufferCoord.Y = 0;

            // keeps track of which screen area write
            SMALL_RECT writeRegion;

            writeRegion.Top = (short)origin.Y;

            int rowsRemaining = rows;

            while (rowsRemaining > 0)
            {
                // Iteration of columns is nested inside iteration of rows.
                // If the size of contents exceeds the buffer limit, writing is
                // done in blocks of size equal to the bufferlimit from left to right
                // then top to bottom.
                // For each iteration of rows,
                // - writeRegion.Left and bufferSize.X are reset
                // - rowsRemaining, writeRegion.Top, writeRegion.Bottom, and bufferSize.Y
                //     are updated
                //   For each iteration of columns,
                //   - writeRegion.Left, writeRegion.Right and bufferSize.X are updated

                writeRegion.Left = (short)origin.X;

                COORD bufferSize;

                bufferSize.X = (short)Math.Min(cols, bufferLimit);
                bufferSize.Y = (short)Math.Min
                                        (
                                            rowsRemaining,
                                            bufferLimit / bufferSize.X
                                        );
                writeRegion.Bottom = (short)(writeRegion.Top + bufferSize.Y - 1);

                // atRow is at which row of contents a particular iteration is operating
                int atRow = rows - rowsRemaining + contents.GetLowerBound(0);

                // number of columns yet to be written
                int colsRemaining = cols;

                while (colsRemaining > 0)
                {
                    writeRegion.Right = (short)(writeRegion.Left + bufferSize.X - 1);

                    // atCol is at which column of contents a particular iteration is operating
                    int atCol = cols - colsRemaining + contents.GetLowerBound(1);
                    CHAR_INFO[] characterBuffer = new CHAR_INFO[bufferSize.Y * bufferSize.X];

                    // copy characterBuffer to contents;
                    for (int r = atRow, characterBufferIndex = 0;
                        r < bufferSize.Y + atRow; r++)
                    {
                        for (int c = atCol; c < bufferSize.X + atCol; c++, characterBufferIndex++)
                        {
                            characterBuffer[characterBufferIndex].UnicodeChar =
                                (ushort)contents[r, c].Character;
                            characterBuffer[characterBufferIndex].Attributes =
                                ColorToWORD(contents[r, c].ForegroundColor, contents[r, c].BackgroundColor);
                        }
                    }

                    // Now writeRegion, bufferSize and characterBuffer are updated.
                    // Call NativeMethods.WriteConsoleOutput
                    bool result =
                        NativeMethods.WriteConsoleOutput(
                            consoleHandle.DangerousGetHandle(),
                            characterBuffer,
                            bufferSize,
                            bufferCoord,
                            ref writeRegion);

                    if (result == false)
                    {
                        // When WriteConsoleOutput fails, half bufferLimit
                        if (bufferLimit < 2)
                        {
                            int err = Marshal.GetLastWin32Error();
                            HostException e = CreateHostException(err, "WriteConsoleOutput",
                                ErrorCategory.WriteError, ConsoleControlStrings.WriteConsoleOutputExceptionTemplate);
                            throw e;
                        }
                        bufferLimit /= 2;
                        if (cols == colsRemaining)
                        {
                            // if cols == colsRemaining, nothing is guaranteed written in this pass and
                            //  the unwritten area is still rectangular
                            bufferSize.Y = 0;
                            break;
                        }
                        else
                        {
                            // some areas have been written. This could only happen when the number of columns
                            // to write is larger than bufferLimit. In that case, the algorithm writes one row
                            // at a time => bufferSize.Y == 1. Then, we can safely leave bufferSize.Y unchanged
                            // to retry with a smaller bufferSize.X.
                            Dbg.Assert(bufferSize.Y == 1, string.Format(CultureInfo.InvariantCulture, "bufferSize.Y should be 1, but is {0}", bufferSize.Y));
                            bufferSize.X = (short)Math.Min(colsRemaining, bufferLimit);
                            continue;
                        }
                    }

                    colsRemaining -= bufferSize.X;
                    writeRegion.Left += bufferSize.X;
                    bufferSize.X = (short)Math.Min(colsRemaining, bufferLimit);
                }  // column iteration

                rowsRemaining -= bufferSize.Y;
                writeRegion.Top += bufferSize.Y;
            }  // row iteration
        }
Exemplo n.º 2
0
        private static void ReadConsoleOutputPlain
        (
            ConsoleHandle consoleHandle,
            Coordinates origin,
            Rectangle contentsRegion,
            ref BufferCell[,] contents
        )
        {
            int rows = contentsRegion.Bottom - contentsRegion.Top + 1;
            int cols = contentsRegion.Right - contentsRegion.Left + 1;

            if ((rows <= 0) || cols <= 0)
            {
                tracer.WriteLine("invalid contents region");
                return;
            }

            int bufferLimit = 2 * 1024; // Limit is 8K bytes as each CHAR_INFO takes 4 bytes

            COORD bufferCoord;

            bufferCoord.X = 0;
            bufferCoord.Y = 0;

            // keeps track of which screen area read
            SMALL_RECT readRegion;

            readRegion.Top = (short)origin.Y;

            int rowsRemaining = rows;

            while (rowsRemaining > 0)
            {
                // Iteration of columns is nested inside iteration of rows.
                // If the size of contents exceeds the buffer limit, reading is
                // done in blocks of size equal to the bufferlimit from left to right
                // then top to bottom.
                // For each iteration of rows,
                // - readRegion.Left and bufferSize.X are reset
                // - rowsRemaining, readRegion.Top, readRegion.Bottom, and bufferSize.Y
                //     are updated
                //   For each iteration of columns,
                //   - readRegion.Left, readRegion.Right and bufferSize.X are updated

                readRegion.Left = (short)origin.X;

                COORD bufferSize;
                bufferSize.X = (short)Math.Min(cols, bufferLimit);
                bufferSize.Y = (short)Math.Min
                                        (
                                            rowsRemaining,
                                            bufferLimit / bufferSize.X
                                        );
                readRegion.Bottom = (short)(readRegion.Top + bufferSize.Y - 1);

                // atContentsRow is at which row of contents a particular iteration is operating
                int atContentsRow = rows - rowsRemaining + contentsRegion.Top;

                // number of columns yet to be read
                int colsRemaining = cols;

                while (colsRemaining > 0)
                {
                    readRegion.Right = (short)(readRegion.Left + bufferSize.X - 1);

                    // Now readRegion and bufferSize are updated.
                    // Call NativeMethods.ReadConsoleOutput
                    CHAR_INFO[] characterBuffer = new CHAR_INFO[bufferSize.Y * bufferSize.X];
                    bool result = NativeMethods.ReadConsoleOutput(
                                        consoleHandle.DangerousGetHandle(),
                                        characterBuffer,
                                        bufferSize,
                                        bufferCoord,
                                        ref readRegion);

                    if (result == false)
                    {
                        // When WriteConsoleOutput fails, half bufferLimit
                        if (bufferLimit < 2)
                        {
                            int err = Marshal.GetLastWin32Error();

                            HostException e = CreateHostException(err, "ReadConsoleOutput",
                                ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleOutputExceptionTemplate);
                            throw e;
                        }
                        // if cols == colsRemaining, nothing is guaranteed read in this pass and
                        //  the unread area is still rectangular
                        bufferLimit /= 2;
                        if (cols == colsRemaining)
                        {
                            bufferSize.Y = 0;
                            break;
                        }
                        else
                        {
                            // some areas have been read. This could only happen when the number of columns
                            // to write is larger than bufferLimit. In that case, the algorithm reads one row
                            // at a time => bufferSize.Y == 1. Then, we can safely leave bufferSize.Y unchanged
                            // to retry with a smaller bufferSize.X.
                            Dbg.Assert(bufferSize.Y == 1, string.Format(CultureInfo.InvariantCulture, "bufferSize.Y should be 1, but is {0}", bufferSize.Y));
                            bufferSize.X = (short)Math.Min(colsRemaining, bufferLimit);
                            continue;
                        }
                    }

                    // atContentsCol is at which column of contents a particular iteration is operating
                    int atContentsCol = cols - colsRemaining + contentsRegion.Left;

                    // copy characterBuffer to contents;
                    int characterBufferIndex = 0;
                    for (int r = atContentsRow; r < bufferSize.Y + atContentsRow; r++)
                    {
                        for (int c = atContentsCol; c < bufferSize.X + atContentsCol; c++, characterBufferIndex++)
                        {
                            contents[r, c].Character = (char)
                                characterBuffer[characterBufferIndex].UnicodeChar;
                            ConsoleColor fgColor, bgColor;
                            WORDToColor(characterBuffer[characterBufferIndex].Attributes,
                                out fgColor,
                                out bgColor);
                            contents[r, c].ForegroundColor = fgColor;
                            contents[r, c].BackgroundColor = bgColor;
                        }
                    }
                    colsRemaining -= bufferSize.X;
                    readRegion.Left += bufferSize.X;
                    bufferSize.X = (short)Math.Min(colsRemaining, bufferLimit);
                }  // column iteration

                rowsRemaining -= bufferSize.Y;
                readRegion.Top += bufferSize.Y;
            }  // row iteration

            // The following nested loop set the value of the empty cells in contents:
            // character to ' '
            // foreground color to console's foreground color
            // background color to console's background color
            int rowIndex = contents.GetLowerBound(0);
            int rowEnd = contents.GetUpperBound(0);
            int colBegin = contents.GetLowerBound(1);
            int colEnd = contents.GetUpperBound(1);
            CONSOLE_SCREEN_BUFFER_INFO bufferInfo =
                        GetConsoleScreenBufferInfo(consoleHandle);
            ConsoleColor foreground = 0;
            ConsoleColor background = 0;

            WORDToColor(
                            bufferInfo.Attributes,
                            out foreground,
                            out background
                       );

            while (rowIndex <= rowEnd)
            {
                int colIndex = colBegin;
                while (true)
                {
                    // if contents[rowIndex,colIndex] is in contentsRegion, hence a non-empty cell,
                    // move colIndex to one past the right end of contentsRegion
                    if (contentsRegion.Top <= rowIndex && rowIndex <= contentsRegion.Bottom &&
                        contentsRegion.Left <= colIndex && colIndex <= contentsRegion.Right)
                    {
                        colIndex = contentsRegion.Right + 1;
                    }
                    // colIndex past contents last column
                    if (colIndex > colEnd)
                    {
                        break;
                    }
                    contents[rowIndex, colIndex].Character = ' ';
                    contents[rowIndex, colIndex].ForegroundColor = foreground;
                    contents[rowIndex, colIndex].BackgroundColor = background;
                    colIndex++;
                }
                rowIndex++;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Wrap32 WriteConsoleOutput.
        /// This wrapper is not limited to 64K or 8K CHAR_INFO to which Win32's WriteConsoleOutput
        /// is constrained.
        /// </summary>
        /// <param name="consoleHandle">
        /// 
        /// handle for the console where output is written
        /// 
        /// </param>
        /// <param name="origin">
        /// 
        /// location on screen buffer where writing starts
        /// 
        /// </param>
        /// <param name="contents">
        /// 
        /// 2D array of cells. Caller needs to ensure that the array is 2D.
        /// 
        /// </param>
        /// <exception cref="HostException">
        /// If Win32's GetConsoleScreenBufferInfo fails
        /// If there is not enough memory to complete calls to Win32's WriteConsoleOutput
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="contents"/> is null
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If it is illegal to write <paramref name="contents"/> to the output buffer 
        /// </exception>

        internal static void WriteConsoleOutput(ConsoleHandle consoleHandle, Coordinates origin, BufferCell[,] contents)
        {
            Dbg.Assert(!consoleHandle.IsInvalid, "ConsoleHandle is not valid");
            Dbg.Assert(!consoleHandle.IsClosed, "ConsoleHandle is closed");
            if (contents == null)
            {
                throw PSTraceSource.NewArgumentNullException("contents");
            }
            uint codePage;
            if (IsCJKOutputCodePage(out codePage))
            {
                // contentsRegion indicates the area in contents (declared below) in which
                // the data read from ReadConsoleOutput is stored.
                Rectangle contentsRegion = new Rectangle();
                ConsoleControl.CONSOLE_SCREEN_BUFFER_INFO bufferInfo =
                    GetConsoleScreenBufferInfo(consoleHandle);

                int bufferWidth = bufferInfo.BufferSize.X;
                int bufferHeight = bufferInfo.BufferSize.Y;
                Rectangle screenRegion = new Rectangle(
                    origin.X, origin.Y,
                    Math.Min(origin.X + contents.GetLength(1) - 1, bufferWidth - 1),
                    Math.Min(origin.Y + contents.GetLength(0) - 1, bufferHeight - 1));

                contentsRegion.Left = contents.GetLowerBound(1);
                contentsRegion.Top = contents.GetLowerBound(0);
                contentsRegion.Right = contentsRegion.Left +
                    screenRegion.Right - screenRegion.Left;
                contentsRegion.Bottom = contentsRegion.Top +
                    screenRegion.Bottom - screenRegion.Top;

#if DEBUG
                //Check contents in contentsRegion
                CheckWriteConsoleOutputContents(contents, contentsRegion);
#endif

                //Identify edges and areas of identical contiguous edges in contentsRegion
                List<BufferCellArrayRowTypeRange> sameEdgeAreas = new List<BufferCellArrayRowTypeRange>();
                int firstLeftTrailingRow = -1, firstRightLeadingRow = -1;
                BuildEdgeTypeInfo(contentsRegion, contents,
                    sameEdgeAreas, out firstLeftTrailingRow, out firstRightLeadingRow);

#if DEBUG
                CheckWriteEdges(consoleHandle, codePage, origin, contents, contentsRegion,
                    bufferInfo, firstLeftTrailingRow, firstRightLeadingRow);
#endif

                foreach (BufferCellArrayRowTypeRange area in sameEdgeAreas)
                {
                    Coordinates o = new Coordinates(origin.X,
                                                    origin.Y + area.Start - contentsRegion.Top);
                    Rectangle contRegion = new Rectangle(
                        contentsRegion.Left, area.Start, contentsRegion.Right, area.End);
                    if ((area.Type & BufferCellArrayRowType.LeftTrailing) != 0)
                    {
                        contRegion.Left++;
                        o.X++;
                        if (o.X >= bufferWidth || contRegion.Right < contRegion.Left)
                        {
                            return;
                        }
                    }

                    WriteConsoleOutputCJK(consoleHandle, o, contRegion, contents, area.Type);
                }
            }
            else
            {
                WriteConsoleOutputPlain(consoleHandle, origin, contents);
            }
        }
Exemplo n.º 4
0
		internal static void ReadConsoleOutputCJK(SafeFileHandle consoleHandle, uint codePage, Coordinates origin, Rectangle contentsRegion, ref BufferCell[,] contents)
		{
			int bottom = contentsRegion.Bottom - contentsRegion.Top + 1;
			int right = contentsRegion.Right - contentsRegion.Left + 1;
			if (bottom <= 0 || right <= 0)
			{
				ConsoleControl.tracer.WriteLine("invalid contents region", new object[0]);
				return;
			}
			else
			{
				int num = 0x800;
				ConsoleControl.SMALL_RECT y;
                y.Top = (short)origin.Y;
				int y1 = bottom;
				while (y1 > 0)
				{
					y.Left = (short)origin.X;
					ConsoleControl.COORD cOORD;
                    cOORD.X = (short)Math.Min(right, num);
					cOORD.Y = (short)Math.Min(y1, num / cOORD.X);
					y.Bottom = (short)(y.Top + cOORD.Y - 1);
					int top = bottom - y1 + contentsRegion.Top;
					int x = right;
					while (x > 0)
					{
						int left = right - x + contentsRegion.Left;
						y.Right = (short)(y.Left + cOORD.X - 1);
						Rectangle rectangle = new Rectangle(left, top, left + cOORD.X - 1, top + cOORD.Y - 1);
						bool flag = ConsoleControl.ReadConsoleOutputCJKSmall(consoleHandle, codePage, new Coordinates(y.Left, y.Top), rectangle, ref contents);
						if (flag)
						{
							x = x - cOORD.X;
							y.Left = (short)(y.Left + cOORD.X);
							if (x > 0 && cOORD.Y == 1 && contents[rectangle.Bottom, rectangle.Right].Character == ' ')
							{
								x++;
								y.Left = (short)(y.Left - 1);
							}
							cOORD.X = (short)Math.Min(x, num);
						}
						else
						{
							if (num >= 2)
							{
								num = num / 2;
								if (right != x)
								{
									cOORD.X = (short)Math.Min(x, num);
								}
								else
								{
									cOORD.Y = 0;
									break;
								}
							}
							else
							{
								int lastWin32Error = Marshal.GetLastWin32Error();
								HostException hostException = ConsoleControl.CreateHostException(lastWin32Error, "ReadConsoleOutput", ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleOutputExceptionTemplate);
								throw hostException;
							}
						}
					}
					y1 = y1 - cOORD.Y;
					y.Top = (short)(y.Top + cOORD.Y);
				}
				int lowerBound = contents.GetLowerBound(0);
				int upperBound = contents.GetUpperBound(0);
				int lowerBound1 = contents.GetLowerBound(1);
				int upperBound1 = contents.GetUpperBound(1);
				ConsoleControl.CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo = ConsoleControl.GetConsoleScreenBufferInfo(consoleHandle);
				ConsoleColor consoleColor = ConsoleColor.Black;
				ConsoleColor consoleColor1 = ConsoleColor.Black;
				ConsoleControl.WORDToColor(consoleScreenBufferInfo.Attributes, out consoleColor, out consoleColor1);
				while (lowerBound <= upperBound)
				{
					int right1 = lowerBound1;
					while (true)
					{
						if (contentsRegion.Top <= lowerBound && lowerBound <= contentsRegion.Bottom && contentsRegion.Left <= right1 && right1 <= contentsRegion.Right)
						{
							right1 = contentsRegion.Right + 1;
						}
						if (right1 > upperBound1)
						{
							break;
						}
						contents[lowerBound, right1] = new BufferCell(' ', consoleColor, consoleColor1, BufferCellType.Complete);
						right1++;
					}
					lowerBound++;
				}
				return;
			}
		}
Exemplo n.º 5
0
		private static void WriteConsoleOutputPlain(SafeFileHandle consoleHandle, Coordinates origin, BufferCell[,] contents)
		{
			int length = contents.GetLength(0);
			int num = contents.GetLength(1);
			if (length <= 0 || num <= 0)
			{
				ConsoleControl.tracer.WriteLine("contents passed in has 0 rows and columns", new object[0]);
				return;
			}
			else
			{
				int num1 = 0x800;
				ConsoleControl.COORD cOORD;
                cOORD.X = 0;
				cOORD.Y = 0;
				ConsoleControl.SMALL_RECT y;
                y.Top = (short)origin.Y;
				int y1 = length;
				while (y1 > 0)
				{
					y.Left = (short)origin.X;
					ConsoleControl.COORD cOORD1;
                    cOORD1.X = (short)Math.Min(num, num1);
					cOORD1.Y = (short)Math.Min(y1, num1 / cOORD1.X);
					y.Bottom = (short)(y.Top + cOORD1.Y - 1);
					int lowerBound = length - y1 + contents.GetLowerBound(0);
					int x = num;
					while (x > 0)
					{
						y.Right = (short)(y.Left + cOORD1.X - 1);
						int lowerBound1 = num - x + contents.GetLowerBound(1);
						ConsoleControl.CHAR_INFO[] character = new ConsoleControl.CHAR_INFO[cOORD1.Y * cOORD1.X];
						int num2 = lowerBound;
						int num3 = 0;
						while (num2 < cOORD1.Y + lowerBound)
						{
							int num4 = lowerBound1;
							while (num4 < cOORD1.X + lowerBound1)
							{
								character[num3].UnicodeChar = contents[num2, num4].Character;
								character[num3].Attributes = ConsoleControl.ColorToWORD(contents[num2, num4].ForegroundColor, contents[num2, num4].BackgroundColor);
								num4++;
								num3++;
							}
							num2++;
						}
						bool flag = ConsoleControl.NativeMethods.WriteConsoleOutput(consoleHandle.DangerousGetHandle(), character, cOORD1, cOORD, ref y);
						if (flag)
						{
							x = x - cOORD1.X;
							y.Left = (short)(y.Left + cOORD1.X);
							cOORD1.X = (short)Math.Min(x, num1);
						}
						else
						{
							if (num1 >= 2)
							{
								num1 = num1 / 2;
								if (num != x)
								{
									cOORD1.X = (short)Math.Min(x, num1);
								}
								else
								{
									cOORD1.Y = 0;
									break;
								}
							}
							else
							{
								int lastWin32Error = Marshal.GetLastWin32Error();
								HostException hostException = ConsoleControl.CreateHostException(lastWin32Error, "WriteConsoleOutput", ErrorCategory.WriteError, ConsoleControlStrings.WriteConsoleOutputExceptionTemplate);
								throw hostException;
							}
						}
					}
					y1 = y1 - cOORD1.Y;
					y.Top = (short)(y.Top + cOORD1.Y);
				}
				return;
			}
		}
Exemplo n.º 6
0
		internal static void WriteConsoleOutput(SafeFileHandle consoleHandle, Coordinates origin, BufferCell[,] contents)
		{
			uint num = 0;
			if (contents != null)
			{
				if (!ConsoleControl.IsCJKOutputCodePage(out num))
				{
					ConsoleControl.WriteConsoleOutputPlain(consoleHandle, origin, contents);
				}
				else
				{
					Rectangle lowerBound = new Rectangle();
					ConsoleControl.CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo = ConsoleControl.GetConsoleScreenBufferInfo(consoleHandle);
					int x = consoleScreenBufferInfo.BufferSize.X;
					int y = consoleScreenBufferInfo.BufferSize.Y;
					Rectangle rectangle = new Rectangle(origin.X, origin.Y, Math.Min(origin.X + contents.GetLength(1) - 1, x - 1), Math.Min(origin.Y + contents.GetLength(0) - 1, y - 1));
					lowerBound.Left = contents.GetLowerBound(1);
					lowerBound.Top = contents.GetLowerBound(0);
					lowerBound.Right = lowerBound.Left + rectangle.Right - rectangle.Left;
					lowerBound.Bottom = lowerBound.Top + rectangle.Bottom - rectangle.Top;
					ConsoleControl.CheckWriteConsoleOutputContents(contents, lowerBound);
					List<ConsoleControl.BufferCellArrayRowTypeRange> bufferCellArrayRowTypeRanges = new List<ConsoleControl.BufferCellArrayRowTypeRange>();
					int num1 = -1;
					int num2 = -1;
					ConsoleControl.BuildEdgeTypeInfo(lowerBound, contents, bufferCellArrayRowTypeRanges, out num1, out num2);
					ConsoleControl.CheckWriteEdges(consoleHandle, num, origin, contents, lowerBound, consoleScreenBufferInfo, num1, num2);
					foreach (ConsoleControl.BufferCellArrayRowTypeRange bufferCellArrayRowTypeRange in bufferCellArrayRowTypeRanges)
					{
						Coordinates coordinate = new Coordinates(origin.X, origin.Y + bufferCellArrayRowTypeRange.Start - lowerBound.Top);
						Rectangle left = new Rectangle(lowerBound.Left, bufferCellArrayRowTypeRange.Start, lowerBound.Right, bufferCellArrayRowTypeRange.End);
						if ((bufferCellArrayRowTypeRange.Type & ConsoleControl.BufferCellArrayRowType.LeftTrailing) != 0)
						{
							left.Left = left.Left + 1;
							coordinate.X = coordinate.X + 1;
							if (coordinate.X >= x || left.Right < left.Left)
							{
								return;
							}
						}
						ConsoleControl.WriteConsoleOutputCJK(consoleHandle, coordinate, left, contents, bufferCellArrayRowTypeRange.Type);
					}
				}
				return;
			}
			else
			{
				throw PSTraceSource.NewArgumentNullException("contents");
			}
		}
Exemplo n.º 7
0
		private static void ReadConsoleOutputPlain(SafeFileHandle consoleHandle, Coordinates origin, Rectangle contentsRegion, ref BufferCell[,] contents)
		{
			ConsoleColor consoleColor = ConsoleColor.Black;
			ConsoleColor consoleColor1 = ConsoleColor.Black;
			int bottom = contentsRegion.Bottom - contentsRegion.Top + 1;
			int right = contentsRegion.Right - contentsRegion.Left + 1;
			if (bottom <= 0 || right <= 0)
			{
				ConsoleControl.tracer.WriteLine("invalid contents region", new object[0]);
				return;
			}
			else
			{
				int num = 0x800;
				ConsoleControl.COORD cOORD;
                cOORD.X = 0;
				cOORD.Y = 0;
				ConsoleControl.SMALL_RECT y;
                y.Top = (short)origin.Y;
				int y1 = bottom;
				while (y1 > 0)
				{
					y.Left = (short)origin.X;
					ConsoleControl.COORD cOORD1;
                    cOORD1.X = (short)Math.Min(right, num);
					cOORD1.Y = (short)Math.Min(y1, num / cOORD1.X);
					y.Bottom = (short)(y.Top + cOORD1.Y - 1);
					int top = bottom - y1 + contentsRegion.Top;
					int x = right;
					while (x > 0)
					{
						y.Right = (short)(y.Left + cOORD1.X - 1);
						ConsoleControl.CHAR_INFO[] cHARINFOArray = new ConsoleControl.CHAR_INFO[cOORD1.Y * cOORD1.X];
						bool flag = ConsoleControl.NativeMethods.ReadConsoleOutput(consoleHandle.DangerousGetHandle(), cHARINFOArray, cOORD1, cOORD, ref y);
						if (flag)
						{
							int left = right - x + contentsRegion.Left;
							int num1 = 0;
							for (int i = top; i < cOORD1.Y + top; i++)
							{
								int num2 = left;
								while (num2 < cOORD1.X + left)
								{
									contents[i, num2].Character = Convert.ToChar(cHARINFOArray[num1].UnicodeChar);
									ConsoleControl.WORDToColor(cHARINFOArray[num1].Attributes, out consoleColor, out consoleColor1);
									contents[i, num2].ForegroundColor = consoleColor;
									contents[i, num2].BackgroundColor = consoleColor1;
									num2++;
									num1++;
								}
							}
							x = x - cOORD1.X;
							y.Left = (short)(y.Left + cOORD1.X);
							cOORD1.X = (short)Math.Min(x, num);
						}
						else
						{
							if (num >= 2)
							{
								num = num / 2;
								if (right != x)
								{
									cOORD1.X = (short)Math.Min(x, num);
								}
								else
								{
									cOORD1.Y = 0;
									break;
								}
							}
							else
							{
								int lastWin32Error = Marshal.GetLastWin32Error();
								HostException hostException = ConsoleControl.CreateHostException(lastWin32Error, "ReadConsoleOutput", ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleOutputExceptionTemplate);
								throw hostException;
							}
						}
					}
					y1 = y1 - cOORD1.Y;
					y.Top = (short)(y.Top + cOORD1.Y);
				}
				int lowerBound = contents.GetLowerBound(0);
				int upperBound = contents.GetUpperBound(0);
				int lowerBound1 = contents.GetLowerBound(1);
				int upperBound1 = contents.GetUpperBound(1);
				ConsoleControl.CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo = ConsoleControl.GetConsoleScreenBufferInfo(consoleHandle);
				ConsoleColor consoleColor2 = ConsoleColor.Black;
				ConsoleColor consoleColor3 = ConsoleColor.Black;
				ConsoleControl.WORDToColor(consoleScreenBufferInfo.Attributes, out consoleColor2, out consoleColor3);
				while (lowerBound <= upperBound)
				{
					int right1 = lowerBound1;
					while (true)
					{
						if (contentsRegion.Top <= lowerBound && lowerBound <= contentsRegion.Bottom && contentsRegion.Left <= right1 && right1 <= contentsRegion.Right)
						{
							right1 = contentsRegion.Right + 1;
						}
						if (right1 > upperBound1)
						{
							break;
						}
						contents[lowerBound, right1].Character = ' ';
						contents[lowerBound, right1].ForegroundColor = consoleColor2;
						contents[lowerBound, right1].BackgroundColor = consoleColor3;
						right1++;
					}
					lowerBound++;
				}
				return;
			}
		}