Created
October 13, 2014 06:36
-
-
Save uemuraj/140b716dee3b3d05fe66 to your computer and use it in GitHub Desktop.
C++ リハビリ勉強中。コンソール出力において属性(文字色や背景色)を指定可能なマニピュレーターを実装してみる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <iostream> | |
using namespace std; | |
// | |
// コンソール出力において属性(文字色や背景色)を指定可能なマニピュレーターを実装します。 | |
// | |
// put_time() や put_money() のスタイルを真似ています。 | |
// | |
template <class _Elem> class put_attr_t | |
{ | |
const _Elem *text; | |
const int attr; | |
public: | |
put_attr_t(const _Elem *t, const int a) : text(t), attr(a) | |
{ | |
} | |
basic_ostream<_Elem, char_traits<_Elem>> &put(basic_ostream<_Elem, char_traits<_Elem>> &os) const; | |
}; | |
const put_attr_t<char> put_attr(const char *text, int attr) | |
{ | |
return put_attr_t<char>(text, attr); | |
} | |
const put_attr_t<wchar_t> put_attr(const wchar_t *text, int attr) | |
{ | |
return put_attr_t<wchar_t>(text, attr); | |
} | |
const put_attr_t<char> put_attr(const string &text, int attr) | |
{ | |
return put_attr_t<char>(text.c_str(), attr); | |
} | |
const put_attr_t<wchar_t> put_attr(const wstring &text, int attr) | |
{ | |
return put_attr_t<wchar_t>(text.c_str(), attr); | |
} | |
template<class _Elem> basic_ostream<_Elem, char_traits<_Elem>> &operator<<(basic_ostream<_Elem, char_traits<_Elem>> &os, const put_attr_t<_Elem> &attr) | |
{ | |
return attr.put(os); | |
} | |
// | |
// Windows 専用の実装です。 http://msdn.microsoft.com/ja-jp/library/cc429756.aspx を参照してください。 | |
// | |
#if _WIN32 | |
#include <windows.h> | |
extern const unsigned long std_out_handle = STD_OUTPUT_HANDLE; | |
extern const unsigned long std_err_handle = STD_ERROR_HANDLE; | |
extern const int red = FOREGROUND_INTENSITY | FOREGROUND_RED; | |
extern const int blue = FOREGROUND_INTENSITY | FOREGROUND_BLUE; | |
extern const int green = FOREGROUND_INTENSITY | FOREGROUND_GREEN; | |
class text_attribute | |
{ | |
HANDLE hConsoleOutput; | |
CONSOLE_SCREEN_BUFFER_INFO csbi; | |
public: | |
text_attribute(unsigned long out, int attr) | |
{ | |
if ((hConsoleOutput = ::GetStdHandle(out)) != INVALID_HANDLE_VALUE) | |
{ | |
if (::GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) | |
{ | |
::SetConsoleTextAttribute(hConsoleOutput, attr & 0xFFFF); | |
} | |
else | |
{ | |
csbi.wAttributes = 0; | |
} | |
} | |
} | |
~text_attribute() | |
{ | |
if (hConsoleOutput != INVALID_HANDLE_VALUE && csbi.wAttributes != 0) | |
{ | |
::SetConsoleTextAttribute(hConsoleOutput, csbi.wAttributes); | |
} | |
} | |
}; | |
#endif | |
// | |
// 汎用になりそうなテンプレート部分です。とりあえず、この段階で cout, cerr, wcout, wcerr を見ています。 | |
// | |
template <class _Elem> basic_ostream<_Elem, char_traits<_Elem>> &put_attr_t<_Elem>::put(basic_ostream<_Elem, char_traits<_Elem>> &os) const | |
{ | |
if (os == cout || os == wcout) | |
{ | |
text_attribute attribute(std_out_handle, attr); | |
return os << text; | |
} | |
if (os == cerr || os == wcerr) | |
{ | |
text_attribute attribute(std_err_handle, attr); | |
return os << text; | |
} | |
return os << text; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
こんな感じで使えるはず。