Click here to Skip to main content
15,886,873 members
Articles / Programming Languages / C++

Coloured Error Messages for Console Applications

Rate me:
Please Sign up or sign in to vote.
4.26/5 (16 votes)
5 Dec 2006CPOL 27.3K   18   2
Implementation of a function which will print coloured messages on console window

Introduction

While working with console applications, sometimes we want to print coloured error messages. Here is the implementation of a very small function which will help in accomplishing the task. 

C++
int _teprintf(TCHAR *format, ...) 
{
    HANDLE hStdOut = NULL ;
    TCHAR szBuffer[1024] ;
    va_list arg_list ;
    int nBuf = 0 ;
    va_start(arg_list,format);
    nBuf = _vsntprintf(szBuffer,1024,format,arg_list) ;
    va_end(arg_list) ;
    //get console output handle
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);    
    if(!hStdout) {
        return 0;
    }
    //set red colour
    if (! SetConsoleTextAttribute(hStdout, FOREGROUND_RED | 
        FOREGROUND_INTENSITY)) {
        return 0;
    }
    //print 
    nBuf = _tprintf(_T("%s"),szBuffer) ;
    //restore to white.
    if (! SetConsoleTextAttribute(hStdout, FOREGROUND_RED |
        FOREGROUND_BLUE | 
        FOREGROUND_GREEN)) {
        return 0;
    }
    return nBuf ;
}

You can use it as follows:

C++
int _tmain(int argc, _TCHAR* argv[])
{
	_teprintf(_T("\nI am Error\n")) ;
	_tprintf(_T("\nI am Normal\n")) ;
	return 0;
}

Though this is trivial, it is fun..!

History

  • 5th December, 2006: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other Microsoft
India India
I am currently working with Microsoft at Bangalore (India). My interest lies in areas of generic C++ and windows development. Apart from office hours I try to develop new and useful small tools.
Well, I still feel that I need to be more serious..!
Smile | :)

Comments and Discussions

 
Generalmore perfect idea Pin
Yacha13-Dec-06 20:52
Yacha13-Dec-06 20:52 
We can use IOStreams to solve this task more perfect.
<br />
main.cpp<br />
...<br />
console::console_buffer<char> out_buf(console::console_buffer<char>::output);<br />
std::basic_streambuf<char>* prev_out_buf = std::wcout.rdbuf(&out_buf);<br />
...<br />
console::color green_color(color::foreground<color::green>::value | color::foreground<color::intensity>::value);<br />
std::cout << green_color << "TEKISUTO WA MIDORIIRO DESU" << console::def_color << std::endl;<br />
....<br />
color.hpp<br />
...<br />
class color<br />
{<br />
public:<br />
	enum colour<br />
	{<br />
          blue = FOREGROUND_BLUE,<br />
	  green = FOREGROUND_GREEN,<br />
	  red = FOREGROUND_RED,<br />
	  intensity = FOREGROUND_INTENSITY<br />
	};<br />
	template<colour c> struct foreground { enum { value = c }; };<br />
	template<colour c> struct background { enum { value = c << 4 }; };<br />
	explicit color(short c)<br />
		: c_(c)<br />
	{<br />
	}<br />
	color()<br />
		: c_(foreground<red>::value | foreground<green>::value | foreground<blue>::value)<br />
	{<br />
	}<br />
	short get() const { return c_; }<br />
	//! set a new color<br />
	template<typename charT><br />
	friend std::basic_ostream<charT>& operator << (std::basic_ostream<charT>& os, color const& c);<br />
private:<br />
	short c_;<br />
};<br />
template<typename charT><br />
inline std::basic_ostream<charT>& operator << (std::basic_ostream<charT>& os, color const& c)<br />
{<br />
	if(os.good())<br />
	{<br />
		//! get current stream buffer<br />
		if(console_buffer<charT>* screen = dynamic_cast<console_buffer<charT>* >(os.rdbuf()))<br />
		{<br />
			os.flush();<br />
			static_cast<void>(screen->set_color(c));<br />
		}<br />
	}<br />
	return os;<br />
}<br />
...<br />
console_buffer.hpp<br />
...<br />
template<typename charT, typename traitsT = std::char_traits<charT> ><br />
class console_buffer<br />
		: public std::basic_filebuf<charT, traitsT><br />
{<br />
public:<br />
	//! available console type<br />
	enum console_type<br />
	{<br />
		devnul	= 0,<br />
		output	= STD_OUTPUT_HANDLE,<br />
		input	= STD_INPUT_HANDLE,<br />
		error	= STD_ERROR_HANDLE<br />
	};<br />
	explicit console_buffer(console_type con_type)<br />
		: con_type_(con_type)<br />
		, console_(0)<br />
	{<br />
		HANDLE h = ::GetStdHandle(con_type);<br />
		//! ran under service or /dev/nul<br />
		if(con_type == devnul || h == 0)<br />
		{<br />
			h = ::CreateFileW(L"NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);<br />
			con_type = devnul;<br />
		}<br />
		if(INVALID_HANDLE_VALUE == h)<br />
			throw std::runtime_error("invalid handle value");<br />
		//! if not /dev/nul, should duplicate handle<br />
		if(con_type != devnul)<br />
		{<br />
			HANDLE dup(0);<br />
			HANDLE process(GetCurrentProcess());<br />
			if(!::DuplicateHandle(process, h, process, &dup, 0, 0, DUPLICATE_SAME_ACCESS))<br />
				throw std::runtime_error("duplicate error");<br />
			h = dup;<br />
		}<br />
		//! opend file descriptor<br />
		int handle = ::_open_osfhandle(reinterpret_cast<::intptr_t>(h), _O_TEXT);<br />
		//! open C file stream<br />
		console_ = ::_fdopen(handle, "a");<br />
		//! initialize basic_filebuf<br />
		std::basic_filebuf<charT, traitsT>::_Init(console_, std::basic_filebuf<charT, traitsT>::_Newfl);<br />
		default_color_ = this->do_get_default_color();<br />
	}<br />
	//! return default screen buffer color<br />
	color default_color() const { return default_color_; }<br />
	//! set new screen buffer color<br />
	color set_color(color const& _new_color)<br />
	{<br />
		HANDLE h = this->get_console_handle();<br />
		if(INVALID_HANDLE_VALUE  != h)<br />
		{<br />
			::CONSOLE_SCREEN_BUFFER_INFO info = { sizeof(CONSOLE_SCREEN_BUFFER_INFO), 0 };<br />
			if(::GetConsoleScreenBufferInfo(h, &info))<br />
			{<br />
				color prev(info.wAttributes & 0x00ff);<br />
				::SetConsoleTextAttribute(h, (info.wAttributes & 0xff00) | _new_color.get());<br />
				return prev;<br />
			}<br />
		}<br />
		return color();<br />
	}<br />
	...<br />
<br />
private:<br />
	color do_get_default_color() const<br />
	{<br />
		HANDLE h = this->get_console_handle();<br />
		if(INVALID_HANDLE_VALUE  != h)<br />
		{<br />
			::CONSOLE_SCREEN_BUFFER_INFO info = { sizeof(CONSOLE_SCREEN_BUFFER_INFO), 0 };<br />
			if(::GetConsoleScreenBufferInfo(h, &info))<br />
				return color(info.wAttributes & 0x00ff);<br />
		}<br />
		return color();<br />
	}<br />
	//! return current console handle<br />
	HANDLE get_console_handle() const<br />
	{<br />
		HANDLE h = INVALID_HANDLE_VALUE;<br />
		int fd = ::_fileno(console_);<br />
		if(fd != -1)<br />
			h = reinterpret_cast<HANDLE>(::_get_osfhandle(fd));<br />
		return h;<br />
	}<br />
private:<br />
	console_type con_type_;//! console type<br />
	::FILE*      console_; //! C file stream<br />
	color        default_color_;//! defaulr console color<br />
};<br />
...<br />
template<typename charT><br />
inline std::basic_ostream<charT>& def_color(std::basic_ostream<charT>& os)<br />
{<br />
	if(os.good())<br />
	{<br />
		//! //! get current stream buffer<br />
		if(console_buffer<charT>* screen = dynamic_cast<console_buffer<charT>* >(os.rdbuf()))<br />
		{<br />
			os.flush();<br />
			static_cast<void>(screen->set_color(screen->default_color()));<br />
		}<br />
	}<br />
	return os;<br />
}<br />

Generalrestore original colors Pin
osy5-Dec-06 23:03
osy5-Dec-06 23:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.