17.3.1 Getting Handles to Console Input and Output

A character-based application receives input from the input buffer, “CONIN$”. StdIn is a handle to “CONIN$”. The application writes to the console window by writing to a screen buffer. StdOut and StdErr are screen buffer handles (TEXTMODE). To access console input and output through either the File functions or the Console functions, you must have open handles to these buffers.

The application may retrieve the StdIn, StdOut, and StdErr handles by calling GetStdHandle. These handles will not be 0–2. GetStdHandle returns an open input handle with read/write access and read/write sharing mode, which may be used with any of the Console or File I/O functions that access the input buffer. The same function returns an open output handle with read/write access and read/write sharing mode, which may be used with any of the Console or File I/O functions that access a TEXTMODE screen buffer. If you use GetStdHandle to get an output screen buffer handle, remember that this is an inherited handle. Consequently, you should avoid changing any of the attributes associated with a screen buffer (e.g., screen buffer size, cursor appearance, scroll position, etc.), or you should save the state of the screen buffer and restore it when your application terminates. Another alternative is to create a new screen buffer for use by your application, leaving the inherited screen buffer unchanged. The following lines show the use of GetStdHandle to open the inherited console handles.

HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);

HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE);

You could use CreateFile to open an input handle with different access or sharing modes, as shown in the following code fragment:

hReadWriteInput = CreateFile("CONIN$",

GENERIC_READ | GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE, /* share handles with cmd */

NULL,

OPEN_EXISTING, /* open already created console */

0, /* normal file open */

NULL

);

Any handle to console input, whether created by GetStdHandle or by CreateFile, can be used in either WaitForSingleObject or WaitForMultipleObjects . The handle will be signalled when the input buffer is non-empty and reset when the buffer is empty.

CreateConsoleScreenBuffer is used to create additional screen buffers. This is used if you want more than one screen buffer. Typically, applications that use the Console functions will use this function to create a private screen buffer, rather than using the StdOut. Creating a new screen buffer has no affect on StdOut or StdErr. The new screen buffer can be made the active screen buffer by calling SetConsoleActiveScreenBuffer which selects it as the screen buffer to display in the console window. Access to a screen buffer may be limited by restricting the file share access or by using the security attributes to set an ACL. This code fragment show the creation of a private TEXTMODE screen buffer to which the application has exclusive access and which will not be inherited by child processes:

SECURITY_ATTRIBUTES SecurityAttributes;

SecurityAttributes.bInheritHandle = FALSE;

SecurityAttributes.lpSecurityDescriptor = NULL;

SecurityAttributes.nLength = sizeof (SECURITY_ATTRIBUTES);

hPrivateScrnBuf = CreateConsoleScreenBuffer(

GENERIC_READ | GENERIC_WRITE,

0, /* no file sharing */

&SecurityAttributes, /* no inheritance */

CONSOLE_TEXTMODE_BUFFER,

NULL

);

When a TEXTMODE screen buffer is created, it contains blanks; its cursor position is at the buffer's origin (0,0), which is displayed at the upper left corner of the window. The initial size of the screen buffer (in character rows and columns) is determined by the user or by system defaults. Use GetConsoleScreenBufferInfo to determine the actual size; and use SetConsoleScreenBufferSize if you want to change its size. Note that the size of a screen buffer may not be made smaller than the size of the console window.