Console Graphics Help!
In the following code, how am I supposed to create a colored bar at the bottom of t开发者_如何学Pythonhe console?? The following code makes the bar at the very top but I wan't to create the bar at the bottom. How am I supposed to do that?
void main(void)
{
HANDLE hOutput = (HANDLE)GetStdHandle( STD_OUTPUT_HANDLE );
// Set the text output position to (5,10)
COORD sPos;
sPos.X = 5;
sPos.Y = 10;
SetConsoleCursorPosition( hOutput, sPos );
// Set the color to bright green
SetConsoleTextAttribute( hOutput,
FOREGROUND_INTENSITY | FOREGROUND_GREEN );
// Write the text
DWORD nWritten;
WriteConsole( hOutput, "This is a test", 14, &nWritten, NULL );
CHAR_INFO buffer[SCREEN_HEIGHT][SCREEN_WIDTH];
COORD dwBufferSize = { SCREEN_WIDTH,SCREEN_HEIGHT };
COORD dwBufferCoord = { 0, 0 };
SMALL_RECT rcRegion = { 0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
WriteConsoleOutput( hOutput, (CHAR_INFO *)buffer, dwBufferSize,
dwBufferCoord, &rcRegion );
}
Use GetConsoleScreenBufferInfo
to obtain a CONSOLE_SCREEN_BUFFER_INFO
structure.
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(hOutput, &bufferInfo);
You can use srWindow
which will give you the coordinates of the corners of the display-window.
Use this to position the bar at the bottom:
// bufferInfo is a structure CONSOLE_SCREEN_BUFFER_INFO.
SMALL_RECT rcRegion =
{
bufferInfo.srWindow.Left,
bufferInfo.srWindow.Top,
SCREEN_WIDTH-1,
SCREEN_HEIGHT-1
};
I am unsure if sr.Window.Left
is ever anything but zero, but lets play safe.
Update 1: I used Bottom
in rcRegion
, it should be Top
. I misunderstood the original code.
Now your code has some problems. First, you are using uninitialized memory and write it to the buffer. It will most typically result in hilarious effects.
Second you need to understand that when you write a big region like that straight into the buffer you'll overwrite anything you had there previously. This includes the text you write at the start.
If you want to preserve it you will first need to read from the buffer, alter it and write back.
Anyhow, how to fix the CHAR_BUFFER
problem:
CHAR_INFO buffer[SCREEN_HEIGHT][SCREEN_WIDTH];
memset(&buffer, 0, sizeof(buffer));
Zero it. This ensures that every character in the buffer will render a black void where it is written.
Then we need to print out our bar. I use the character for lower case O here.
for (int i = 0; i < SCREEN_WIDTH; i++)
{
buffer[SCREEN_HEIGHT - 1][i].Char.AsciiChar = 'o';
buffer[SCREEN_HEIGHT - 1][i].Attributes = FOREGROUND_BLUE;
}
This should be pretty straightforward. You write a o
to the last row in the buffer. We also tell it to make it blue. You can use "wide characters" (unicode) instead if you like, UnicodeChar = L'å'
.
This will render a result like:
You can see some of the remaining problems here. Our buffer does not overwrite all of the screen area, leaving some pieces intact (you can see the result from cl.exe
there in the margins.)
Why this is should be pretty obvious: SCREEN_*
does not correspond to the actual width and height of the window.
Also my prompt ends up in the middle of the block, but that is mainly because our program does not clean up after exit. It is not visible until termination.
精彩评论