/// <summary> /// CheckForLineScroll() looks at the console's top line and tries to determine if any lines have vanished as the console has scrolled up. It is an imperfect /// check in that it can be fooled, and a more thorough console validation would be required for certainty, but it is good for identifying some "delta" situations /// where the console can be re-synced simply by removing some lines at the top. /// </summary> /// <param name="Stale">Set to true if CheckForLineScroll() has determined that the console is sufficiently out-of-sync with the tracker that the /// line scroll check cannot be performed reliably.</param> /// <returns>The number of lines which have vanished from the top of the console.</returns> public int CheckForLineScroll(out bool Stale) { if (PendingReload) { PendingReload = false; Stale = true; return(0); } // Force first read to always give Stale so we use GetWholeConsole(). ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO info = Console.GetInfo(); if (info.dwCursorPosition.Y < LastCursorPosition.Y) { Stale = true; return(0); } Stale = false; ConsoleApi.CHAR_INFO[] LineBuffer = new ConsoleApi.CHAR_INFO[info.dwSize.X]; COORD LineBufferSize = new COORD(); LineBufferSize.X = info.dwSize.X; LineBufferSize.Y = 1; COORD Origin = new COORD(); Origin.X = Origin.Y = 0; ConsoleApi.SMALL_RECT ConsoleRect = new ConsoleApi.SMALL_RECT(); ConsoleRect.Left = 0; ConsoleRect.Right = (short)(info.dwSize.X - 1); ConsoleRect.Top = (short)0; ConsoleRect.Bottom = (short)0; // Read the top of the console to compare against our current state Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect); StringBuilder sbLine = new StringBuilder(); for (int xx = 0; xx < info.dwSize.X; xx++) { sbLine.Append(LineBuffer[xx].UnicodeChar); } string FirstLine = sbLine.ToString().TrimEnd(); sbLine.Clear(); if (Lines.Count > 0 && Lines[0] != FirstLine) { for (int yy = 0; yy < Lines.Count; yy++) { if (Lines[yy] == FirstLine) { Lines.RemoveRange(0, yy); return(yy); } } Stale = true; return(0); } return(0); }