Console Graphics!

In the following code, how should I create a color bar at the bottom of the console? The following code makes the panel at the very top, but I will not create the panel at the bottom. How am I supposed to do this?

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 ); } 
+4
source share
1 answer

Use GetConsoleScreenBufferInfo to get CONSOLE_SCREEN_BUFFER_INFO .

 CONSOLE_SCREEN_BUFFER_INFO bufferInfo; GetConsoleScreenBufferInfo(hOutput, &bufferInfo); 

You can use srWindow , which will give you the coordinates of the corners of the screen window.

Use this to position the bar below:

 // bufferInfo is a structure CONSOLE_SCREEN_BUFFER_INFO. SMALL_RECT rcRegion = { bufferInfo.srWindow.Left, bufferInfo.srWindow.Top, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 }; 

I'm not sure that sr.Window.Left always nothing but zero, but it allows you to play safely.

Update 1: I used Bottom in rcRegion , it should be Top . I misunderstood the source code.


Now your code has some problems. First, you use uninitialized memory and write it to the buffer. This usually leads to fun effects.

Secondly, you need to understand that when you write a large area, similar to that located directly in the buffer, you overwrite everything that you had before. This includes the text you write at the beginning.

If you want to save it, you will first need to read from the buffer, change it and write.

Anyway, how to fix the CHAR_BUFFER problem:

 CHAR_INFO buffer[SCREEN_HEIGHT][SCREEN_WIDTH]; memset(&buffer, 0, sizeof(buffer)); 

Zero. This ensures that each character in the buffer displays a black void where it is written.

Then we need to print our bar. I use the lowercase O character 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; } 

It should be pretty simple. You write o to the last line in the buffer. We also say that it be blue. You can use "wide characters" (unicode), if you want, UnicodeChar = L'Γ₯' .

This will produce a result, for example:

Console output on Win7 x86-64

Here you can see some of the remaining problems. Our buffer does not overwrite the entire area of ​​the screen, leaving some parts intact (you can see the result from cl.exe where there are fields).

Why this should be pretty obvious: SCREEN_* does not match the actual width and height of the window.

Also, my request ends in the middle of the block, but this happens mainly because our program is not cleared after exiting. It does not appear until completion.

+2
source

All Articles