Wednesday, November 11, 2009

14.6 Other Capabilities



< BACK  NEXT >

[oR]


14.6
Other Capabilities


Several other functions in the console API make it easy to implement advanced capabilities in your consoles. For example, consoles support the concept of an active buffer, and allow you to change the active buffer at any time. Listing 14.8 demonstrates the process.





Listing 14.8 Switching between two buffers


// 2buff.cpp

#include <windows.h>
#include <iostream.h>
#include <string.h>

void ErrorHandler(char *s, DWORD err)
{
cout << s << endl;
cout << "Error number: " << err << endl;
ExitProcess(err);
}

void ShowBuffers(HANDLE consoleStdin,
HANDLE consoleStdout, HANDLE newBuffer)
{
char buffer[1000];
DWORD numRead, numWrite;
BOOL flag=TRUE;
int x;

for (x=0; x<10; x++)
{
WriteFile(consoleStdout, "Black\n", 6,
&numWrite, 0);
WriteFile(newBuffer, "White\n", 6, &numWrite,
0);
}
do
{
ReadFile(consoleStdin, buffer, 1000,
&numRead, 0);
if (flag)
SetConsoleActiveScreenBuffer(newBuffer);
else
SetConsoleActiveScreenBuffer(
consoleStdout);
flag = !flag;
WriteFile(consoleStdout, buffer, numRead,
&numWrite, 0);
} while (strncmp(buffer, "quit", 4) != 0);
}

VOID main(void)
{
HANDLE consoleStdout, consoleStdin;
HANDLE newBuffer;
// Get handles for standard in and out
consoleStdin = GetStdHandle(STD_INPUT_HANDLE);
consoleStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// they must be invalid if equal
if (consoleStdin == consoleStdout)
ErrorHandler("In GetStdHandle",
GetLastError());
// Create second buffer

newBuffer = CreateConsoleScreenBuffer(
GENERIC_READ | GENERIC_WRITE,
0, 0, CONSOLE_TEXTMODE_BUFFER, 0);

// Show the two different buffers
ShowBuffers(consoleStdin, consoleStdout,
newBuffer);
}


The code in Listing 14.8 starts by getting the input and output handles for the console. It then creates a new screen buffer using the CreateConsole ScreenBuffer function.





































CreateConsoleScreenBuffer

Creates a new screen buffer



HANDLE CreateConsoleScreenBuffer(
DWORD accessFlags,
DWORD shareMode,
LPSECURITY_ATTRIBUTES security,
DWORD type,
PVOID reserved)


accessFlags

GENERIC_READ and/or GENERIC_WRITE

shareMode

FILE_SHARE_READ and/or FILE_SHARE_WRITE

security

Security attributes. See Chapter 10

type

Must currently be CONSOLE_TEXTMODE_BUFFER

reserved

Reserved. Set to 0.

Returns a handle to the new buffer or INVALID_HANDLE_VALUE on error



The new buffer initially has the same size as the existing console window. You can change it (or any console's buffer size) using the SetConsoleScreenBufferSize function.


























SetConsoleScreenBufferSize

Sets the specified buffer to a new size



BOOL SetConsoleScreenBufferSize(
HANDLE consoleHandle, COORD size)


consoleHandle

Handle to the console to change

size

The new console size

Returns TRUE on success



Listing 14.8 simply uses the default size. It then calls the ShowBuffers function. This function demonstrates how to use two separate buffers. The function starts by placing 10 lines of information into the two buffers. Then, each time the user presses the Enter key, the program sets the active buffer using the SetConsoleActiveScreenBuffer function.






















SetConsoleActiveScreenBuffer

Sets the active output buffer for the process's console to the buffer specified



BOOL SetConsoleActiveScreenBuffer(
HANDLE consoleHandle)

consoleHandle

Handle to the console

Returns TRUE on success



Processes can have just one console window, and just one con- sole input stream, but can also have many different output buffers. The Set ConsoleActiveScreenBuffer function lets you choose among them. As soon as the function is called, the new buffer will appear and the scroll bars will change as necessary to accommodate the new buffer.



Another interesting capability involves coloring the output buffer, or placing characters directly into it. Listing 14.9 demonstrates coloring.





Listing 14.9 Changing the color of the output buffer


// color.cpp

#include <windows.h>
#include <iostream.h>

void ErrorHandler(char *s, DWORD err)
{
cout << s << endl;
cout << "Error number: " << err << endl;
ExitProcess(err);
}

// Changes the colors of a range of cells.
// Make sure that the console you are
// using is not so big that the area
// colored is not off the screen.
void ChangeColors(HANDLE consoleStdin,
HANDLE consoleStdout)
{
COORD c;
WORD color;
DWORD numWrite;
BOOL success;

// Fill in the color of a range of 200 cells.
color = BACKGROUND_RED | FOREGROUND_GREEN;
c.X = 20;
c.Y = 10;
success = FillConsoleOutputAttribute(
consoleStdout, color, 200, c, &numWrite);
cout < numWrite < endl;
if (!success)
ErrorHandler("In FillConsoleOutputAttribute",
GetLastError());
}

VOID main(void)
{
HANDLE consoleStdout, consoleStdin;

// Get handles for standard in and out
consoleStdin = GetStdHandle(STD_INPUT_HANDLE);
consoleStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (consoleStdin == consoleStdout)
ErrorHandler("In GetStdHandle",
GetLastError());

// Process user I/O
ChangeColors(consoleStdin, consoleStdout);
}


Every cell in the output buffer has an X-Y coordinate, a character, and a color-attribute byte. The code in Listing 14.9 simply modifies the attribute bytes of a set of 200 characters:





color = BACKGROUND_RED | FOREGROUND_GREEN;
c.X = 20;
c.Y = 10;
success = FillConsoleOutputAttribute(
consoleStdout, color, 200, c, &numWrite);



The FillConsoleOutputAttribute function (like the nearly identical WriteConsoleOut putAttribute function) accepts a color byte, a starting position, and the number of characters to apply the color to. It changes their color attributes.






































FillConsoleOutputAttribute

Fills in the color attribute bytes of a range of character positions in the buffer



BOOL FillConsoleOutputAttribute(
HANDLE consoleHandle,
WORD color,
DWORD numberOfCells,
COORD startingCoord,
LPDWORD numWritten)


consoleHandle

Handle to the console

color

The new attribute byte

numberOfCells

Number of cells to change

startingCoord

The coordinates of the starting character

numWritten

Number of cells actually changed

Returns TRUE on success



The color byte can contain combinations of red, green, and blue or black for both the foreground and background colors. The FillConsole OutputAttribute function fills runs of cells line by line, starting at the indicated position.



The SetConsoleTextAttribute function sets the color attribute byte and applies it to all characters that subsequently appear in the text output buffer.


























SetConsoleTextAttribute

Sets the color attribute byte for all subsequent output



BOOL SetConsoleTextAttribute(
HANDLE consoleHandle,
WORD attribute)

consoleHandle

Output console handle

attribute

The attribute byte

Returns TRUE on success



Two other useful convenience functions are GetConsoleTitle and SetConsoleTitle, which get and set the verbiage in the title bar of the console's window.























SetConsoleTitle

Sets the console's title



BOOL SetConsoleTitle(
LPTSTR title)


title

The new title

Returns TRUE on success


























GetConsoleTitle

Gets the console's title



DWORD GetConsoleTitle(
LPTSTR buffer,
DWORD numRead)



buffer

The buffer in which to place the title

numRead

The size of the buffer

Returns the number of characters copied to the buffer, or 0 on error





< BACK  NEXT >


No comments:

Post a Comment