Coloured letters in output

I wrote (several years ago) a program to play Upwords (see http://en.wikipedia.org/wiki/Upwords) on the PC in Turbo Pascal. The game (an offshoot of Scrabble) allows tiles (letters) to be put one on top of another - up to five and it was doing fine until a friend went to Win7 (64Bit).

I have rewritten it in C++ but cannot find (or work out) how to change the colours of the letters on the board. I used the colour coding:

1 letter displayed in white
2 letters displayed as green
3 letters displayed as yellow
4 letters displayed as blue
5 letters displayed as red.

Can anyone give me a clue as to how to do this in C++ ??
There's no generic C++ mechanism. But as you mention Windows 7, you could use the Win32 API call SetConsoleTextAttribute().

There are a number of posts on this forum if you need more details. e.g. "Change color of selected text"
http://www.cplusplus.com/forum/general/48596/
(see Duoas' post near end of thread)

Andy

PS The approach for Linux terminals that support vt100 emulation involves escape sequences. See (e.g.) "So You Like Color--The Mysterious ^[[ Characters"
http://www.linuxjournal.com/article/8603
Last edited on
err... system("color 09");, etc? sorry, i don't know how to do it without using the system
Last edited on
Thanks for both inputs. Might be a bit difficult to do the first as I'm still using WinXP on this PC (along with Ubuntu!).

I had thought of using the system() as I've already used system("cls") - I'll experiment with that path first.

K
Please, don't use system("color"). This works more or less the same, using windows.h:
1
2
3
4
5
6
7
8
9
void SetColor(int value){
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  value);
}

int main(){
    SetColor(/*Number*/);
    cout << "I'm in color!";
    /*Your favorite pausing goes here*/
}


1: Blue
2: Green
3: Cyan
4: Red
5: Purple
6: Yellow (Dark)
7: Default white
8: Gray/Grey
9: Bright blue
10: Brigth green
11: Bright cyan
12: Bright red
13: Pink/Magenta
14: Yellow
15: Bright white
-Numbers after 15 are background colors-


Or, if you're interested (Pretty cool, huh?):

1
2
3
4
5
6
7
8
9
10
11
12
13
char* Color(int color=7, char* Message = ""){
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
    return Message;
}

int main()
{
    cout << Color(12,"\N Hey! I'm in color!"); //Sets a color and prints the text
    cout << Color(10," Nice C:\n"); //Sets another color and prints the text
    Color(); //Sets the color to default
    /*Your favorite pausing goes here*/
    return 0;
}
Last edited on
/*Your favorite pausing goes here*/

Please don't use system().
Yeah, don't use system never, I always use simple functions like:

1
2
3
4
5
6
#include <iostream>

void Pause(){
    std::cout << "\nPress enter key to continue\n"
    cin.sync(); cin.ignore();
}


1
2
3
4
5
6
7
#include <iostream>
#include <conio.h>

void Pause(){
    std::cout << "\nPress any key to continue\n";
    kbhit(); getch();
}
Last edited on
Yeah, don't use system never (unless you don't have another option, like when wanting to clear the screen)

http://www.cplusplus.com/articles/4z18T05o/
Another SIMPLE option... Well, better for me to shut up already, just bad excuses, i'll start using some strange window functions
Last edited on
Tried the SYSTEM("COLOR N") which changed *everything* on the screen - your solution, Samrux, does exactly what I wanted... Now I'll try and understand what (and how) it does it! Many thanks

K
I'm glad to help you! The second example I showed to you works in a very simple way, the return value of the function is a string (char*), and returns the value you entered calling the function (after setting a color to the text) to cout. Then prints the text. Using Color(/*Number*/) will just change the color of the text until you decide to change it again, and Color() will set it to default. This works with default arguments when making the function. Remember: Only change the color once per cout statement.
Last edited on
FYI

Samrux's SetConsoleTextAttribute based code is just a simpler variant on Duoas' code which I provided a link to earler in this thread. It will work on Windows XP as well as Windows 7 (and all the way back to Windows NT 3.1!)

Note that Duos code correctly takes account of the fact that the text attribute value passed to SetConsoleTextAttribute() is not just the foreground color. It is also the background and some other stuff. For example, if you had configured your console to use a background color other than black, then setting just the foreground color to blue would lose the background color.

Andy

PS I use alternative background colors for consoles which have particular build environments set up, etc. Then the "default" color is no longer white on black. So you really need to store defaults when the program starts (need a GetColor() as well as a setter)
Last edited on
If you want to work with operator<< more idiomatically, you can define you own manipulator (like std::hex, std::setw(). ...). For this to work, you need to define a little helper class.

Based on samrux's SetColor() function above.

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
// example.h (header guard omitted)

// color setter
inline void SetColor(WORD color){
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}

// helper class
class color {
public:
	color(WORD val) : m_val(val) { }

	void set() const {
		SetColor(m_val);
	}

private:
	WORD m_val;
};

// instances of helper class to avoid need to remember 4 is red, etc
static const color red(4);
static const color green(2);
static const color blue(1);
static const color white(7);
// etc

// overload operator<< to get manipulator to work
inline std::ostream& operator<<(std::ostream& os, const color& c) {
	c.set();
	return os;
}


and

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// example.cpp

#include <iostream>
#include <iomanip>
#include "example.h"

using namespace std;

int main() {
    SetColor(3);
    cout << "I'm in color!\n";

    cout << red << "red " << color(2) << "green " << blue << "blue!!" << endl;

    return 0;
}
Last edited on
Topic archived. No new replies allowed.