第58章 コンソールアプリで文字色を変える


今回は、VC++4.0以降で作ることのできるコンソールアプリケーションについて 解説します。これは、DOSのプログラムを書くのとほとんど同じ方法で作ることが できます。ただし、見た目はDOSのプログラムですが32ビットアプリケーションになります。 従ってDOS窓では動きますが、DOSモード(「スタート」「Windowsの終了」 「MS-DOSモードで再起動する」)では動きません。


さて、このコンソールアプリでCの勉強をしている方も多いでしょう。 困ったことにこのプログラムではエスケープシーケンスがうまく使えません。 (機種によっては使えるそうです。) 文字の色を変えたり、特定の場所に文字を表示したりすることが できなくてはつまりません。

でも、これにかわる方法は用意されています。

コンソールAPIというのを使います。
SetConsoleTextAttribute関数とかSetConsoleCursorPosition 関数を使います。長い関数名ですが関数名を見るだけで 何をする関数なのか想像がつきます。

BOOL SetConsoleTextAttribute( HANDLE hConsoleOutput, // コンソールスクリーンバッファのハンドル WORD wAttributes // テキストと背景の色 );

これじゃさっぱりわからん!!

BOOL, HANDLE, WORDとかいうのはintとかcharのようなデータ型 だと思ってください。Windows関係のプログラミングではこのような 訳のわからんデータ型が山のように出てきます。 (元をたどるとintとかcharとか普通のデータ型をtypedefしたものです) スクリーンバッファのハンドルを指定して、第2引数に色を指定します。 これは、FOREGROUND_RED, FOREGROUND_GREEN, FOREGROUND_BLUEの 組み合わせで指定します。(光の3原色です。白なら全部指定します。) また、FOREGROUND_INTENSITYはその色を強調します。 組み合わせは「|」で行います。

では、スクリーンバッファはどうやって取得するのでしょうか。 これは、

HANDLE GetStdHandle( DWORD nStdHandle // 入出力、エラーデバイス );

を使います。

この場合出力デバイスを指定するのでnStdHandleにはSTD_OUTPUT_HANDLE を指定します。

では、サンプルのプログラムを見てみましょう。

// con01.c #include <windows.h> #include <stdio.h> #include <conio.h> int main(void) { HANDLE hStdout; WORD wAttributes; CONSOLE_SCREEN_BUFFER_INFO csbi;//構造体です hStdout = GetStdHandle(STD_OUTPUT_HANDLE); //hStdoutのコンソールスクリーンバッファ情報をcsbiに取得 GetConsoleScreenBufferInfo(hStdout, &csbi); wAttributes = FOREGROUND_GREEN; SetConsoleTextAttribute(hStdout, wAttributes); printf("緑です wAttributes = %d\n", wAttributes); wAttributes = FOREGROUND_RED; SetConsoleTextAttribute(hStdout, wAttributes); printf("赤です wAttributes = %d\n", wAttributes); wAttributes = FOREGROUND_BLUE; SetConsoleTextAttribute(hStdout, wAttributes); printf("青です wAttributes = %d\n", wAttributes); wAttributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; SetConsoleTextAttribute(hStdout, wAttributes); printf("白です wAttributes = %d\n", wAttributes); wAttributes = wAttributes | FOREGROUND_INTENSITY; SetConsoleTextAttribute(hStdout, wAttributes); printf("強調表示です wAttributes = %d\n", wAttributes); wAttributes = wAttributes | BACKGROUND_BLUE | BACKGROUND_INTENSITY; SetConsoleTextAttribute(hStdout, wAttributes); printf("バックを青の強調にしました wAttributes = %d\n", wAttributes); //元のテキスト状態に戻す SetConsoleTextAttribute(hStdout, csbi.wAttributes); //何かキーを打つと終了 getch(); return 0; }

コンソールAPIを使うためにはwindows.hをインクルードしておきます。

いきなりCONSOLE_SCREEN_BUFFER_INFOという変なのが出てきましたが これは、コンソールスクリーンバッファに関する情報を納める構造体です。

typedef struct _CONSOLE_SCREEN_BUFFER_INFO { // csbi COORD dwSize; COORD dwCursorPosition; WORD wAttributes; SMALL_RECT srWindow; COORD dwMaximumWindowSize; } CONSOLE_SCREEN_BUFFER_INFO ;

というように定義されています。typedefしてあるので CONSOLE_SCREEN_BUFFER_INFOをデータ型のように扱えます。
 

CONSOLE_SCREEN_BUFFER_INFO csbi;

と書くのは int a;とかchar a;というのと同じような使い方です。 こういう手法はウィンドウズ関係のプログラムではよく使われます。

GetConsoleScreenBufferInfo(hStdout, &csbi);

で初期状態をcsbiに格納できます。

BOOL GetConsoleScreenBufferInfo( HANDLE hConsoleOutput, PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo );

PCONSOLE_SCREEN_BUFFER_INFOはCONSOLE_SCREEN_BUFFER_INFO 構造体へのポインタのことです。

あとは、プログラムを順番に見ていってください。 ごちゃごちゃしていますがそんなに難しくはありません。 文字の色を変えるのにこんなに面倒なことをしなくては・・・ とお思いの方は自分で色を変える関数を作っておくと 便利です。

テキストの色を変えたとき参考までにwAttributesの値を 表示するようにしてみました。青は1、緑は2、赤は4です。 白は、これらを全部足した7になっています。

ちなみに背景の青は0x0010、緑は0x0020、赤は0x0040、強調は0x0080 となっています。これらの値を足していくと背景の色を変えることになります。 (ヒント:第49章


[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Jun/16/1998 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。