Visual Studio 2010!

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.
ADVERTISEMENT
ADVERTISEMENT

 

DevSource.com: Your Source for Visual Studio on Facebook
ADVERTISEMENT
Working with Console Screen Buffers in .NET
By Jim Mischel

Rate This Article: Add This Article To:

Working with Console Screen Buffers in .NET - ' Reading Console Output '
( Page 6 of 6 )

Reading Console Output

Yes, you read that right. You can read the output. More correctly, you can read character and attribute data from the screen buffer. That opens some interesting possibilities, such as copying data from one screen buffer to another, or writing a program that "reads" the screen in much the same way that a person would read the screen.

The console API defines three functions that read information from the screen buffer. ReadConsoleOutputCharacter reads a string of consecutive characters from the screen buffer into an array. ReadConsoleOutputAttribute reads consecutive character attributes (foreground and background colors) into an array. These two functions correspond directly to the WriteConsoleOutputCharacter and WriteConsoleOutputAttribute API functions. They are exposed in ConsoleScreenBuffer as ReadXY and ReadAttributesXY.

The other function, ReadConsoleOutput reads a rectangular block of characters and attributes into a rectangular array. This function reads in the same way that WriteConsoleOutput writes, and is exposed in ConsoleScreenBuffer as ReadBlock.

The code in Listing 5 is intended to be placed in Listing 4 before the switch back to the first screen buffer. That is, insert Listing 5 after the call to Console.ReadKey and before the call to JConsole.SetActiveScreenBuffer(sb1). This code reads characters and attributes from the first screen buffer and writes them to the second screen buffer.

Listing 5: Reading the screen buffer

// Show reading screen buffer...
sb2.WriteXY("Copied with ReadXY, ReadAttributesXY", 0, 1);
string chars = sb1.ReadXY(50, 0, 1);
sb2.WriteXY(chars, 0, 2);
ConsoleCharAttribute[] attrs = sb1.ReadAtrributesXY(50, 0, 1);
sb2.WriteAttributesXY(attrs, 50, 0, 2);

sb2.WriteXY("Copied with ReadBlock/WriteBlock", 0, 3);
ConsoleCharInfo[,] block = new ConsoleCharInfo[10, 20];
sb1.ReadBlock(block, 0, 0, 20, 100, 40, 110);
sb2.WriteBlock(block, 0, 0, 0, 4, 20, 14);

Console.ReadKey();

Full Screen Mode

You can set the console to full screen mode so that the console display occupies the entire display area. In full screen mode, the console has full control over the display hardware. There is no Windows border and the task bar is not displayed. Full screen mode can be quite useful on machines that are dedicated to a single console mode application. In addition, output to the console is much faster in full screen mode than in windowed mode. However, full screen mode does have some restrictions.

The most important restriction is that you cannot change the size of the screen buffer window. When you change to full screen mode, the console subsystem enlarges the screen buffer and the screen buffer window if necessary to ensure that it addresses the entire visible screen. Any attempt to change the size of the screen buffer window while in full screen mode will fail.

You can, however, change the size of the screen buffer. Provided, of course, that you make it at least as large as the screen buffer window.

Although the API documentation implies that you can set the display mode for individual screen buffers, that is not the case. If you attempt to set the display mode for a screen buffer that is not the active screen buffer, the call fails. This restriction isn't surprising, but I am surprised that the SetConsoleDisplayMode function expects a screen buffer handle as a parameter.

You can switch to full screen mode by calling SetDisplayMode on a ConsoleScreenBuffer object instance. To get the current display mode, read the DisplayMode property. In keeping with the .NET coding guidelines, I implemented setting the display mode as a method rather than as a writeable property because setting the display mode takes a few seconds (to switch hardware display modes), and has serious side effects — it takes over the entire screen.

When you call SetDisplayMode, you must pass either ConsoleDisplayMode.Windowed or ConsoleDisplayMode.Fullscreen. Although the value ConsoleDisplayMode.FullscreenHardware is returned by the OutputMode property to indicate that the console has completed the transition from windowed to full screen is complete, if you try to set the display mode to that value, the call will fail.

Screen Buffers Add Flexibility

The best thing about console screen buffers is that they give you incredible flexibility in how you build your application. By creating multiple screen buffers, you can keep many different displays updated at all times and switch between them by setting the active screen buffer. In addition, the enhanced output methods let you more easily control where data is written to the screen buffer and how it appears.

The ability to read character and attribute information from a screen buffer provides some interesting possibilities in addition to just copying data from one buffer to another. For example, you could automate output debugging by writing a program that continually examines the screen buffer contents to ensure that it is being displayed correctly. Or, you could use the screen buffer as a communications medium between two applications that share a console.

It's unfortunate, but understandable, that the .NET Framework's System.Console class does not support screen buffers. However, with JConsole and the ConsoleScreenBuffer class, you have the best of both worlds: standard console output for programs with simple needs, and access to the full power of the Windows Console API for those programs that need it.

Full source code, including the entire ConsoleDotNet namespace and all sample programs from this series is available here.



 
 
>>> More Using Microsoft Visual Studio Articles          >>> More By Jim Mischel