Max C
Max C

Reputation: 409

Is it possible to change text color and background color in the console to different colors while still on the same line? C++

Some of the solutions I've found don't seem to work on my terminal on Windows. Only changing the text to one color for the entirety of the line. Example:

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 0 | 15);
cout << 1;

hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole,5 | 0);
cout << 2;

Only changes the text and background to one color. Thanks for any help!

Upvotes: 1

Views: 4144

Answers (1)

Cody Gray
Cody Gray

Reputation: 244712

Yes, it is possible. The reason it isn't working for you is because your code is wrong. You never set a background color; you just manipulate the foreground color.

The source of the problem is almost certainly the fact that you're using magic numbers (0 | 15 and 5 | 0) instead of the constants that are defined in <Windows.h>:

#define FOREGROUND_BLUE      0x0001 // text color contains blue.
#define FOREGROUND_GREEN     0x0002 // text color contains green.
#define FOREGROUND_RED       0x0004 // text color contains red.
#define FOREGROUND_INTENSITY 0x0008 // text color is intensified.
#define BACKGROUND_BLUE      0x0010 // background color contains blue.
#define BACKGROUND_GREEN     0x0020 // background color contains green.
#define BACKGROUND_RED       0x0040 // background color contains red.
#define BACKGROUND_INTENSITY 0x0080 // background color is intensified.

The following code works fine for me:

const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

// yellow on blue
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE);
std::cout << 1;

// blue on bright green
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY);
std::cout << 2;

// reset to black on white
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::cout << std::endl;

Here's a screenshot of my console window as proof that it works. (But note that my console's colors have been customized to the Tango theme, so yours will probably use slightly different colors.)

I recommend making life easier on yourself by defining an enum:

enum ConsoleColors
{
   BlackFore   = 0,
   MaroonFore  = FOREGROUND_RED,
   GreenFore   = FOREGROUND_GREEN,
   NavyFore    = FOREGROUND_BLUE,
   TealFore    = FOREGROUND_GREEN | FOREGROUND_BLUE,
   OliveFore   = FOREGROUND_RED | FOREGROUND_GREEN,
   PurpleFore  = FOREGROUND_RED | FOREGROUND_BLUE,
   GrayFore    = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
   SilverFore  = FOREGROUND_INTENSITY,
   RedFore     = FOREGROUND_INTENSITY | FOREGROUND_RED,
   LimeFore    = FOREGROUND_INTENSITY | FOREGROUND_GREEN,
   BlueFore    = FOREGROUND_INTENSITY | FOREGROUND_BLUE,
   AquaFore    = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE,
   YellowFore  = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN,
   FuchsiaFore = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE,
   WhiteFore   = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,

   BlackBack   = 0,
   MaroonBack  = BACKGROUND_RED,
   GreenBack   = BACKGROUND_GREEN,
   NavyBack    = BACKGROUND_BLUE,
   TealBack    = BACKGROUND_GREEN | BACKGROUND_BLUE,
   OliveBack   = BACKGROUND_RED | BACKGROUND_GREEN,
   PurpleBack  = BACKGROUND_RED | BACKGROUND_BLUE,
   GrayBack    = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
   SilverBack  = BACKGROUND_INTENSITY,
   RedBack     = BACKGROUND_INTENSITY | BACKGROUND_RED,
   LimeBack    = BACKGROUND_INTENSITY | BACKGROUND_GREEN,
   BlueBack    = BACKGROUND_INTENSITY | BACKGROUND_BLUE,
   AquaBack    = BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_BLUE,
   YellowBack  = BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN,
   FuchsiaBack = BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE,
   WhiteBack   = BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
};

and then set colors like this:

SetConsoleTextAttribute(hConsole, ConsoleColors::BlackBack |
                                  ConsoleColors::RedFore));

Upvotes: 7

Related Questions