Change entire console background color (Win32 C++)
Asked Answered
U

7

11

How can I change the entire console's background color? I've tried SetConsoleTextAttribute and it only changes the background color of new text.

I effectively want the entire console to turn red when a serious error arises.

Thanks to everyone who attempts to help.

Ultimatum answered 23/6, 2011 at 21:40 Comment(4)
Sounds like it's an easy job in C#, but in C++.. :| Didn't find anything on a quick googling. Maybe just set text background to red and print a whole array of characters, mostly whitespace, with your text inside, also on red background? I think that could qualify as a workaround.Ligula
This is trivial in Windows command language: color 4f, and that's it. :-)Harlanharland
@Alf: Which means this could work: system("cmd /c \"color 4F\"").Breathtaking
@Loadmaster That works great. I know it's not usually recommended, not portable, etc., but I think it's my only option at this point. Unless I could figure out how to do the same thing COLOR does in C++ (which I'm sure is possible).Ultimatum
A
6

Try something like:

system("color c2");
Azevedo answered 24/6, 2011 at 1:14 Comment(3)
+1 simple but effective even if it is slower to use a system call.Syne
I ended up going with this. I would have preferred an API function, but this is so simple and works great.Ultimatum
not working ! it change text color and text background color not entire consol's colorBewhiskered
H
6

I think the FillConsoleOutputAttribute function will do what you need. Set it to the starting coordinate of the console, and set nLength to the number of characters in the console (width * length).

BOOL WINAPI FillConsoleOutputAttribute(
  __in   HANDLE hConsoleOutput,
  __in   WORD wAttribute,
  __in   DWORD nLength,
  __in   COORD dwWriteCoord,
  __out  LPDWORD lpNumberOfAttrsWritten
);
Helenehelenka answered 23/6, 2011 at 21:45 Comment(2)
Very close, but the cells that already contain characters remain the previous background color.Ultimatum
Guess my Win32/Console is a bit rusty. Can you try WriteConsoleOutputAttribute instead? That might be what you're looking for.Helenehelenka
A
6

Try something like:

system("color c2");
Azevedo answered 24/6, 2011 at 1:14 Comment(3)
+1 simple but effective even if it is slower to use a system call.Syne
I ended up going with this. I would have preferred an API function, but this is so simple and works great.Ultimatum
not working ! it change text color and text background color not entire consol's colorBewhiskered
M
3

I know this is an old question, but how about this code:

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


VOID WINAPI SetConsoleColors(WORD attribs);


int main() {

    SetConsoleColors(BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);

    std::cout << "Hello, world!" << std::endl;
    std::cin.get();

    return 0;
}


VOID WINAPI SetConsoleColors(WORD attribs) {
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

    CONSOLE_SCREEN_BUFFER_INFOEX cbi;
    cbi.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
    GetConsoleScreenBufferInfoEx(hOutput, &cbi);
    cbi.wAttributes = attribs;
    SetConsoleScreenBufferInfoEx(hOutput, &cbi);
}

As far as I know this code should work on Windows Vista and later versions. By the way, this code is based on this article (mainly the sources on the article): http://cecilsunkure.blogspot.fi/2011/12/windows-console-game-set-custom-color.html

Marotta answered 27/1, 2016 at 8:25 Comment(1)
For some reason this solution is causing my console window to shrink every color changeAforementioned
M
1

It can be done and the whole background can be set to desired color with SetConsoleScreenBufferInfoEx. The code below should not mess with the previous console output, especially if it used colors:

 #include "Windows.h"

    void FlashConsoleBackgroundColor(int cntFlashes, int flashInterval_ms, COLORREF color)
    {

        CONSOLE_SCREEN_BUFFER_INFOEX sbInfoEx;
        sbInfoEx.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);

        HANDLE consoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
        GetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);

        COLORREF storedBG = sbInfoEx.ColorTable[0];

        for (int i = 0; i < cntFlashes; ++i)
        {
            //-- set BG color
            Sleep(flashInterval_ms);
            sbInfoEx.ColorTable[0] = color;
            SetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);

            //-- restore previous color
            Sleep(flashInterval_ms);
            sbInfoEx.ColorTable[0] = storedBG;
            SetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);
        }
    }

    int main()
    {

        printf("Flashing console BG: RED");
        FlashConsoleBackgroundColor(20, 50, RGB(255, 0, 0));

        printf("\rFlashing console BG: ORANGE\n");
        FlashConsoleBackgroundColor(10, 100, RGB(255, 105, 0));

        return 0;
    }
Mortie answered 10/10, 2017 at 0:13 Comment(2)
How is this answer different than: @MaGetzUb's answer above? They both show how to use GetConsoleScreenBufferInfoEx and SetConsoleScreenBufferInfoEx only your answer seems to be needlessly more complex.Derain
Actually, my code is quite different in functionality even though it looks similar. @MaGetzUb's code changes the foreground and background color of all characters that have the same attributes as the last printed line. If you haven't used SetConsoleTextAttribute before that then the whole background changes. However add before: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x96); printf("Some previous console output\n"); ..and it fails. My example changes only one color, the color of background regardless what was printed before. Also as a bonus you can set it to custom RGB.Mortie
G
1
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(out, 0x9 | 0x70); 
// text color from 0x1-0x9
// text background color from 0x10-0x90   
system("color d1");
/*
Sets the default console foreground and background colors     
COLOR [attr]      
attr        Specifies color attribute of console output       
Color attributes are specified by TWO hex digits -- the first
corresponds to the background; the second the foreground.  Each digit
can be any of the following values:       
            0 = Black       8 = Gray
            1 = Blue        9 = Light Blue
            2 = Green       A = Light Green
            3 = Aqua        B = Light Aqua
            4 = Red         C = Light Red
            5 = Purple      D = Light Purple
            6 = Yellow      E = Light Yellow
            7 = White       F = Bright White
If no argument is given, this command restores the color to what it was
when CMD.EXE started.  This value either comes from the current console
window, the /T command line switch or from the DefaultColor registry
value.       
The COLOR command sets ERRORLEVEL to 1 if an attempt is made to execute
the COLOR command with a foreground and background color that are the
same.
/*
Gonzalo answered 25/11, 2019 at 8:43 Comment(0)
T
0

This works for me. It changes the background color without messing up the foreground color of text already displayed, by changing each console character cell, one at a time. You will need to get the handle to your console output buffer, which I believe is done with GetStdHandle().

DWORD written = 0;
COORD writeCoord = {0};
WORD attribute;
for (int y = 0; y < consoleBufferLength; y++)     // rows
{
    for (int x = 0; x < consoleBufferWidth; x++)  // columns
    {
        writeCoord.X = x; writeCoord.Y = y;
        ReadConsoleOutputAttribute(consoleOutputHandle, &attribute, 1, writeCoord, &written);
        attribute &= 0xFF0F;  // zero the background color
        attribute |= 12 << 4; // change the background color to red
        FillConsoleOutputAttribute(consoleOutputHandle, attribute, 1, writeCoord, &written);
    }
}
Tenishatenn answered 12/5, 2013 at 15:37 Comment(0)
H
0

I have a dirty way here, but gives what you exactly want.

  #include <windows.h>
  hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  SetConsoleTextAttribute(hConsole,30);
  system("CLS");

console

Hann answered 23/5, 2019 at 19:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.