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:
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:

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.