开发者

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:

Console Graphics Help!

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜