views:

84

answers:

2

Hi, I was building a "reverse console" (so that the written lines would append themselves on the top instead of the bottom) as I stumbled upon a very strange behavior of the Console.MoveBufferArea method:

    static void Main()
    {
        for (var _linesWritten = 0; _linesWritten < 1000; _linesWritten++)
        {
            var _height = Math.Min(Console.BufferHeight-1, _linesWritten);
            Console.MoveBufferArea(0, 0, Console.BufferWidth, _height, 0, 1);
            Console.SetCursorPosition(0, 0);
            Console.WriteLine("Line {0} aaaaaaaaaa", _linesWritten);
            Console.ResetColor();
        }
    }

When i call it a fixed number of times it throws an System.IO.IOException saying: "Not enough storage is available to process this command". I figured out that it depends on the amount of the buffer area being moved around. The number of lines written before the exception is thrown changes as I change the Console.BufferWidth property.

Screenshot

I am running Windows 7 x64 @ Corei7, 6gb DDR3, so storage shuldn't be the problem.... Does anybody have a clue what could be wrong?

A: 

The Console is not just another Window. It's really intended to allow bi-directional input, shell level redirection, etc, and can have some odd issues when you try to do things like this. This is mainly due to the fact that you're working with file stream buffers, not just text on a screen.

Have you considered just making a Window to host your "console" information, since you're obviously doing a non-standard output stream? You could just redirect your Console I/O to your own stream (here is a sample of doing this in VB.NET), and display this in a window yourself, using something like a RichTextBox.

If you're doing a "reversed" console, you're obviously not using the command line redirection facilities, or input mechanisms - in which case a custom window is probably a nicer approach.

Reed Copsey
A: 

The API function that causes the exception is ReadConsoleOutput(). The SDK doc has some relevant small print:

lpBuffer:

*A pointer to a destination buffer that receives the data read from the console screen buffer. This pointer is treated as the origin of a two-dimensional array of CHAR_INFO structures whose size is specified by the dwBufferSize parameter. The total size of the array must be less than 64K.*

I bolded the relevant phrase. Your program will bomb when it tries to scroll more than 200 lines (201 x 80 x 4 = 64320 bytes, oddly off a bit from 65536). It is arguably a bug in the Console.MoveBufferArea(), it doesn't check for this limitation nor tries to work around it which would be easy to do. You can report the bug at connect.microsoft.com

For now, you'll have to limit the number of lines so the buffer size doesn't exceed the limit.

Hans Passant