Knowledge Sharing

C++ Demo 002 : 让 STL 中的 cout 输出彩色的文字

缘起:

  这是一个从 CodeProject 上看到的小程序,很有意思。原文里面没有任何对代码的解释和说明,这里摘过来,做个笔记。

  程序的原作者 :Vincent Godin

 

题目:

  写一个程序,让 STL 中的 cout 输出彩色的文字到显示器上。

 

环境:

  Windows XP Professional sp3 下面用 GNU GCC 的编译器编译,它支持标准C++。推荐使用!*^_^*

 

实验步骤:

  1,新建一个文本文件,命名 "console_color.h" 。

  2,粘贴一下代码到此 .h 文件中。

console_color.h
// ConsoleColor.h
#ifndef _CONSOLE_COLOR_H_
#define _CONSOLE_COLOR_H_

#include
<iostream>
#include
<windows.h>

inline std::ostream
& blue(std::ostream &s)
{
HANDLE hStdout
= GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE
|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
return s;
}

inline std::ostream
& red(std::ostream &s)
{
HANDLE hStdout
= GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_RED
|FOREGROUND_INTENSITY);
return s;
}

inline std::ostream
& green(std::ostream &s)
{
HANDLE hStdout
= GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_GREEN
|FOREGROUND_INTENSITY);
return s;
}

inline std::ostream
& yellow(std::ostream &s)
{
HANDLE hStdout
= GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_GREEN
|FOREGROUND_RED|FOREGROUND_INTENSITY);
return s;
}

inline std::ostream
& white(std::ostream &s)
{
HANDLE hStdout
= GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_RED
|FOREGROUND_GREEN|FOREGROUND_BLUE);
return s;
}

struct color {
color(WORD attribute):m_color(attribute){};
WORD m_color;
};

template
<class _Elem, class _Traits>
std::basic_ostream
<_Elem,_Traits>&
operator<<(std::basic_ostream<_Elem,_Traits>& i, const color& c)
{
HANDLE hStdout
=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,c.m_color);
return i;
}

#endif
// Copyleft Vincent Godin

  3,另外,新建一个文本文件,命名"console_color_test.cpp"

  4,粘贴一下代码到此 .cpp 文件中。

console_color_test.cpp
#include "console_color.h"

int main()
{
std::cout
<< green << "绿色的文本哦。" << red << "这个是红的吧!"
<< white << std::endl;
std::cout
<< color(FOREGROUND_RED|FOREGROUND_GREEN)
<< "This text has a really exiting color ! -- edited by Vincent"
<< white << std::endl;
return 0;
}

  5,利用 GCC 编译这个文件。

g++ console_color_test.cpp -o main

  6,在控制台输入 main 运行程序,看看效果吧。有点意思。

    

 

讨论:

//核心代码段,举一个函数说一下,其他的函数都是换了参数而已。
inline std::ostream& blue(std::ostream &s)
{
HANDLE hStdout
= GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE
|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
return s;
}

  整个函数就是定义了一个用于输出流的控制符,看过 std::endl 的定义吗,呵呵,就是模仿它了。

  这里面用到了两个函数,GetStdHandle SetConsoleTextAttribute

  HANDLE GetStdHandle( DWORD nStdHandle);

    这个函数用来获取标准输入、输出以及标准错误设备的句柄。

  BOOL SetConsoleTextAttribute( HANDLE hConsoleOutput, WORD wAttributes);

    用来设置控制台文本的属性,更多的内容查看 MSDN 吧。我也懒得翻译了,都非常容易明白。

    color 结构体不说了,非常简单。

  剩下来的,就是这个重载的 << 操作符。仔细看一下,Vincent 这哥们用了模板来实现,第一个参数是一个输出流的对象,第二个参数就是个 color 结构体,用来传入结构体中放入的颜色属性。*^_^*

 


template <class _Elem, class _Traits>
std::basic_ostream<_Elem,_Traits>&
operator<<(std::basic_ostream<_Elem,_Traits>& i, const color& c)
{
HANDLE hStdout
=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,c.m_color);
return i;
}

 

总结:

  本文是对 Win32 API 关于 Console 这一块的一个小应用,还是有点意思的。至少,把这个封装成 lib 后,你可以让你的 Console 变得更可爱一点。不再是默认的黑白配了。-_-!

 

参考资料:

  [1] MSDN Console Functions (Windows) : http://msdn.microsoft.com/en-us/library/ms682073%28v=VS.85%29.aspx

  [2] CodeProject Command line processing (Add color to your std::cout) : http://www.codeproject.com/KB/cpp/cout_color.aspx

posted @ 2010-09-16 11:23  Hang Pan  阅读(1845)  评论(0编辑  收藏  举报