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.

Smurf64
  • 337
  • 1
  • 6
  • 15
  • Sounds like it's an [easy job in C#](http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/05b36a5c-40c7-4815-84e7-e813066637b4), 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. – Xeo Jun 23 '11 at 21:45
  • This is trivial in Windows command language: `color 4f`, and that's it. :-) – Cheers and hth. - Alf Jun 23 '11 at 22:02
  • @Alf: Which means this could work: `system("cmd /c \"color 4F\"")`. – David R Tribble Jun 23 '11 at 22:13
  • @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). – Smurf64 Jun 23 '11 at 23:56

7 Answers7

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
);
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
Adam Maras
  • 26,269
  • 6
  • 65
  • 91
  • 1
    Very close, but the cells that already contain characters remain the previous background color. – Smurf64 Jun 23 '11 at 21:53
  • Guess my Win32/Console is a bit rusty. Can you try [WriteConsoleOutputAttribute](http://msdn.microsoft.com/en-us/library/ms687407%28v=VS.85%29.aspx) instead? That might be what you're looking for. – Adam Maras Jun 23 '11 at 22:31
6

Try something like:

system("color c2");
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
wxffles
  • 864
  • 6
  • 20
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

MaGetzUb
  • 31
  • 3
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;
    }
Killzone Kid
  • 6,171
  • 3
  • 17
  • 37
  • 1
    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. – Kyle Shanafelt Oct 10 '17 at 00:51
  • 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. – Killzone Kid Oct 10 '17 at 10:55
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.
/*
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);
    }
}
Pulseczar
  • 150
  • 8
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

no more sigsegv
  • 468
  • 5
  • 17