Easy Color Use

Hey guys, I wanted to ask a design question, but I'm still a massive noob so...

The long and short of it is I want to use colors for the first time (noob) in console I found online for a little Tic Tac Toe game for practice, but I want 4 different colors that will be rotated often. The player gets green, computer red, unused numbers blue, and a bright white board. Well, you can probably guess that I want to make it easier to switch between them without needing the entire name. I tried to alias it because... I'm an idiot. And my enum doesn't seem to be working well either...

1
2
3
4
5
6
7
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
enum Color {
	white = SetConsoleTextAttribute(hConsole, 15),
	blue = SetConsoleTextAttribute(hConsole, 9),
	red = SetConsoleTextAttribute(hConsole, 12),
	green = SetConsoleTextAttribute(hConsole, 10)
};


I looked up HANDLE and thought maybe it was similar to an alias, but that didn't work either. Putting it into a struct didn't work either (though I AM considering how to make a specialized text class that I can pass a character/string and color for simplification).

Really, any simple solution is a good solution. You can PROBABLY see what I'm getting at/was going for in the above code.
This is the very basics. It could be wrapped up better, but I haven't time for better right now. (Sorry.)

colors.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifndef COLORS_HPP
#define COLORS_HPP

enum Color
{
  black = 0,
  
  dblue,                dark_blue       = dblue,
  dgreen,               dark_green      = dgreen,
  dcyan,                dark_cyan       = dcyan,
  dred,                 dark_red        = dred,
  dmagenta,             dark_magenta    = dmagenta,
  dyellow,              dark_yellow     = dyellow,      brown   = dyellow,
        
  lgray,                light_gray      = lgray,
  lgrey = lgray,        light_grey      = lgray,
  dgray,                dark_gray       = dgray,
  dgrey = dgray,        dark_grey       = dgray,
        
  lblue,                light_blue      = lblue,
  lgreen,               light_green     = lgreen,
  lcyan,                light_cyan      = lcyan,
  lred,                 light_red       = lred,
  lmagenta,             light_magenta   = lmagenta,
  lyellow,              light_yellow    = lyellow,      yellow = lyellow,
  
  white
};

Color GetBackgroundColor();
Color GetForegroundColor();
void SetColor( Color fg, Color bg );
void SetColor( Color fg );

#endif 

colors.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "colors.hpp"

#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>

Color GetBackgroundColor()
{
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &csbi );
  return (Color)((csbi.wAttributes & 0xF0) >> 4);
}

Color GetForegroundColor()
{
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &csbi );
  return (Color)(csbi.wAttributes & 0x0F);
}

void SetColor( Color fg, Color bg )
{
  SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), (int)(bg << 4) | (int)fg );
}

void SetColor( Color fg )
{
  SetColor( fg, GetBackgroundColor() );
}

a.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

#include "colors.hpp"

int main()
{
  // Save initial state
  Color initial_colors[] = { GetForegroundColor(), GetBackgroundColor() };
  
  SetColor( lyellow, dred );
  cout << "  Surprise!  ";
  SetColor( dgreen, initial_colors[1] );
  cout << "\n It's alive!";
  SetColor( initial_colors[0] );
  cout << "\n";
  
  // Restore initial state
  SetColor( initial_colors[0], initial_colors[1] );
}

Hope this helps.
SetConsoleTextAttribute(hConsole, 15) - a function call
white = SetConsoleTextAttribute(hConsole, 15) - assign the result of the function call to white.

Consulting documentation, the type returned from SetConsoleTextAttribute is BOOL. Assuming that each call is successful white, blue, red and green will all be equal to the same value which has absolutely nothing to do with color and everything to do with whether some function calls succeeded or failed.

1
2
3
4
5
6
7
8
9
10
void textcolor(Color c) {
    setConsoleTextAttribute(hConsole, int(c));
}

enum Color { 
    white = 15,
    blue = 9,
    red = 12,
    green = 10
};


... then just call textcolor(x); where x is white, blue, red or green.
This is the very basics. It could be wrapped up better, but I haven't time for better right now. (Sorry.)


No, this is fantastic! Far more than I expected, in fact, to the point I'm going to need to look most (if not all) of it up to see what the individual functions and whatnot do haha!

Thanks a million man! I wanted to add colors because colors are fun, people like them, and they make console programs (for this particular application at least) easier to read, but under no circumstance did I want to call SetConsoleTextAttribute() to set a single character, then call it again to change it back every time XD

EDIT: You guys? Brilliant.
Last edited on
SetConsoleTextAttribute() is a very lightweight function. Call it as often as you need.
Topic archived. No new replies allowed.