Gaining Access to Console Mode Information

There are a number of environmental considerations when working with the console. The most important considerations are the mode in which the console is operating at any given time. For example, you might want to display data differently when the console is in full screen mode, than when it operates as a window. The two console mode-specific functions are GetConsoleDisplayMode() and GetConsoleMode(). You might need GetLargestConsole-WindowSize() function on occasion, to learn how big you can make the console window. If you want to change the current console mode, use the SetConsoleMode() function. Listing 6.3 shows several of these functions in action. You'll find the source code for the example in the \Chapter 06\C#\ConsoleMode and \Chapter 06\VB\ConsoleMode folders on the CD.

Note Listing 6.3 omits some of the code we've already discussed as part of Listing 6.1. Please refer to the ClearScreen example for explanations of the GetStdHandle() function and associated enumerations. The ClearScreen example also shows how to use the COORD structure.

Listing 6.3: Methods Used to Access Console Mode Information

// Obtains the current display mode—fullscreen or fullscreen hardware. [DllImport("Kernel3 2.DLL")]

public static extern bool GetConsoleDisplayMode(ref UInt32 lpModeFlags);

// An enumeration used to determine public enum ConsoleDispMode {

CONSOLE_WINDOWED = 0,

CONSOLE_FULLSCREEN = 1,

CONSOLE_FULLSCREEN_HARDWARE = 2

the current display mode.

// Only implied by function. // The console is fullscreen. // The console owns the hardware.

// Obtains the size of the largest console window possible.

[DllImport("Kernel3 2.DLL")] public static extern COORD

GetLargestConsoleWindowSize(IntPtr hConsoleOutput);

// Returns the console mode information. [DllImport("Kernel3 2.DLL")]

public static extern bool GetConsoleMode(IntPtr hConsoleHandle, ref UInt32 lpMode);

public enum ModeFlags {

// Input mode flags

ENABLE_PROCESSED_INPUT = 0x0001,

ENABLE_LINE_INPUT = 0x0002,

ENABLE_ECHO_INPUT = 0x0004,

ENABLE_WINDOW_INPUT = 0x0008,

ENABLE_MOUSE_INPUT = 0x0010,

// Output mode flags

ENABLE_PROCESSED_OUTPUT = 0x0001,

ENABLE WRAP AT EOL OUTPUT = 0x0 0 02

[STAThread]

static void Main(string[] {

UInt32 DisplayMode =

IntPtr hOut;

IntPtr hin;

COORD ScreenSize;

UInt32 ConsoleMode =

args)

// The current display mode.

// Handle to the output device.

// Handle to the input device.

// Maximum screen size.

// The console mode information.

// Get the current display mode, if (GetConsoleDisplayMode(ref DisplayMode))

// Determine if the console is in windowed mode, if (DisplayMode == (UInt32)ConsoleDispMode.CONSOLE_WINDOWED) Console.WriteLine("Console is in windowed mode.");

// If the console is fullscreen mode, determine which // of the potential conditions are true.

switch (DisplayMode) {

case (UInt32)ConsoleDispMode.CONSOLE_FULLSCREEN:

Console.WriteLine("Console is in fullscreen mode."); break;

case (UInt32)ConsoleDispMode.CONSOLE_FULLSCREEN_HARDWARE: Console.WriteLine("Console has hardware access."); break;

case (UInt32)ConsoleDispMode.CONSOLE_FULLSCREEN +

(UInt32)ConsoleDispMode.CONSOLE_FULLSCREEN_HARDWARE: Console.WriteLine("Console is in fullscreen mode and " + "has access to the hardware.");

break;

// If the call failed, register an error.

Console.WriteLine("No Display Mode Information Available");

// Obtain a handle to the console screen and console input. hIn = GetStdHandle(StdHandleEnum.STD_INPUT_HANDLE); hOut = GetStdHandle(StdHandleEnum.STD_OUTPUT_HANDLE);

// Determine the largest screen size possible. ScreenSize = GetLargestConsoleWindowSize(hOut);

// Display the information.

Console.WriteLine("\r\nThe largest console window size is:" +

"\r\n Columns: " + ScreenSize.X.ToString() + "\r\n Rows: " + ScreenSize.Y.ToString());

// Get the console mode information.

Console.WriteLine("\r\nConsole Mode Information:");

// Retrieve the input information.

if (GetConsoleMode(hIn, ref ConsoleMode)) {

if ((ConsoleMode & (UInt32)ModeFlags.ENABLE_ECHO_INPUT) == (UInt32)ModeFlags.ENABLE_ECHO_INPUT) Console.WriteLine(" Echo Input Enabled");

if ((ConsoleMode & (UInt32)ModeFlags.ENABLE_LINE_INPUT) == (UInt32)ModeFlags.ENABLE_LINE_INPUT) Console.WriteLine(" Line Input Enabled");

if ((ConsoleMode & (UInt32)ModeFlags.ENABLE_MOUSE_INPUT) == (UInt32)ModeFlags.ENABLE_MOUSE_INPUT) Console.WriteLine(" Mouse Input Enabled");

if ((ConsoleMode & (UInt32)ModeFlags.ENABLE_PROCESSED_INPUT) == (UInt32)ModeFlags.ENABLE_PROCESSED_INPUT) Console.WriteLine(" Processed Input Enabled");

if ((ConsoleMode & (UInt32)ModeFlags.ENABLE_WINDOW_INPUT) == (UInt32)ModeFlags.ENABLE_WINDOW_INPUT) Console.WriteLine(" Window Input Enabled");

// Retrieve the output information.

if (GetConsoleMode(hOut, ref ConsoleMode)) {

if ((ConsoleMode & (UInt32)ModeFlags.ENABLE_PROCESSED_OUTPUT) == (UInt32)ModeFlags.ENABLE_PROCESSED_OUTPUT) Console.WriteLine(" Processed Output Enabled");

if ((ConsoleMode & (UInt32)ModeFlags.ENABLE_WRAP_AT_EOL_OUTPUT) == (UInt32)ModeFlags.ENABLE_WRAP_AT_EOL_OUTPUT) Console.WriteLine(" Wrap at End of Line Enabled");

// Wait until the user is done viewing the information. Console.Write("\r\nPress any key when ready..."); Console.Read();

This example shows some of the anomalies you'll need to consider when working with the Win32 API. Several of the previous examples have shows API functions that return an HRESULT—essentially an error code. The GetConsoleDisplayMode() and GetConsoleMode() in this example return a bool, which is a simple pass/fail indicator for the function call. On the other hand, the GetLargestConsoleWindowSize() function returns a COORD structure, which means you have neither an error result nor a pass/fail indicator until you attempt to use the data contained within the structure.

The code begins with a call to the GetConsoleDisplayMode() function. If you read the Platform SDK documentation for this function, you'll notice that it only refers to two return values: CONSOLE_FULLSCREEN_HARDWARE and CONSOLE_FULLSCREEN. The problem is that there's an actual third value of CONSOLE_WINDOWED. The code reflects this fact and you'll find that the need for the undocumented value is practical as well. The one important issue to consider is that a windowed console application will never use the CONSOLE_FULLSCREEN_HARDWARE value, so the code reflects this fact too. The GetConsoleDisplayMode() function requires that you pass a UInt32 variable by reference, not as an out variable. In other words, you must initialize the variable before you pass it or you might receive unpredictable results.

The GetLargestConsoleWindowSize() function call comes next. Notice that you must supply a standard output handle for this function. We'll find with the GetConsoleMode() function that this isn't necessarily true for all Win32 API calls. The GetLargestConsoleWindowSize() function returns a COORD structure containing the largest window you can create for the console referenced by the handle you provide. The screen buffer might not provide the required amount of memory for a full-sized screen, so you need to keep what's possible separate from what the console can support. You can use the SetConsoleScreenBufferSize() function to resize the window to maximum using the results from this call.

Using the GetLargestConsoleWindowSize() function in full-screen mode will yield different results from windowed mode. The reason is that the full-screen mode is controlled by a different set of settings from the windowed mode. To change the full-screen mode settings, you can right-click the title bar of the console window and choose Properties from the context menu. The Options tab contains settings to switch from windowed for full-screen operation. The Layout tab shown in Figure 6.2 enables you to change the screen buffer settings, which also determines the output from the GetLargestConsoleWindowSize() function. However, if the user uses the MODE command to change the size of the window, it doesn't affect the output from the GetLargestConsoleWindowSize() function because the output is based upon the screen buffer size, not the window size.

Screen Buffer Size Oracle

Figure 6.2: Use the settings on the Layout tab to change the output from the GetLargestConsoleWindowSize() function.

The GetConsoleMode() function is next on the list. It's important to note that you can provide either a screen buffer (standard output) or an input handle for this function. However, the results you obtain will directly reflect the kind of handle you pass to the function. Consequently, the example code shows what happens for both an input and an output handle. The handle tells you the mode settings for both input and output as determined by the handle provided. All of the mode settings except window input are enabled by default. The Platform SDK documentation explains the various settings in detail.

Now that you have some idea of what the console mode functions do, let's look at the example in action. Figure 6.3 shows the windowed output from the example. The full-screen output is different, so you'll want to test both modes. As you can see, the example correctly detects the windowed state of the console window, the largest size the console window will allow, and which mode settings the console window has enabled.

■ D:¥HH Sourc* CMteCNaptrf 06VC*VCm«m

»toModsUilnVMiug^Cor

naMlodr.fa

HIE

The UrMil <»n«ol« tflMtev flit It: CelMwia: 144 Row: 1 (9

0

Coiiult ftod* Inform«! Echo Input Enabled Lin« Input Inablfd flout* Input ln«hled Proctned Input Enabled Prac<::*d Oiitpit tnahlnd Ur-p m% (Ml of Lin« l*«fcl«4l

Figure 6.3: The example application demonstrates the usefulness of the console mode information.

Was this article helpful?

0 0

Post a comment