ゴミ溜め@技術系日常系雑文

主にWeb技術やそのほかつまづいたこととか引っかかって調べたこととかをまとめてます。

はてなダイアリーから引っ越しました。)

Win32::Console を使って、Windowsコマンドプロンプトの文字色を変える

みんな大好き黒画面。だけどたまにはカラフルにしたい。
たとえば、エラー出力を赤文字に!
あるいは、警告文を黄色文字に!

そんなときにはこの方法で。

環境

CPANから Win32::Console をインストール(or Update)

私の環境は Strawberry Perl なので、CPANから取ってくる。
Active Perlの人はPPMから。

cpan> install Win32::Console

使い方

色を変えるには、下記の通り実行するだけ。

use strict;
use Win32::Console;

our $console = new Win32::Console(STD_OUTPUT_HANDLE);
my $attr = $console->Attr; # 初期設定値を取得。

$|=1; # バッファリング無効化 (※)

my $bg = 1;
my $fg = 12;
$console->Attr(($bg << 4) | $fg); # 以降の標準出力時の色が変わる。 (※)
print "Hello ";

$bg = 13;
$fg = 11;
$console->Attr(($bg << 4) | $fg); # 以降の標準出力時の色が変わる。 (※)
print "world!";

$console->Attr($attr); # 標準設定に戻す。(※)

すると、以下のようになる。
f:id:AyeBee_TY:20140903203537p:plain

解説

7行目:$console->Attr(($bg << 4) | $fg);
改行単位ごとに1つのバッファとしてまとめて出力しようとするため、設定した文字色が、行全体にかかってしまうのを防ぐ目的として、バッファリングを解除しています。

11,16行目:$console->Attr(($bg << 4) | $fg);
背景色4ビット+文字色4ビットの計8ビットで表現されるため、背景色を4ビット左シフトし、文字色をORしています。
f:id:AyeBee_TY:20140903191423p:plain

19行目:$console->Attr($attr);
最後に、元の設定値に戻しておきます。
でないと、以降の表示内容も色づけされてしまうため。

使える色について

使える色は0~15の全16個。(→ANSI カラー xterm16)
ためしに全部出力してみると、

use strict;
use Win32::Console;

our $console = new Win32::Console(STD_OUTPUT_HANDLE);

my $attr = $console->Attr;   # 初期値を取得
# my $def_bg = $attr >> 4;   # 初期背景色を取得
# my $def_fg = ($attr & 15); # 初期文字色を取得

$|=1; # バッファリング無効化 (※)

print "## 背景色\n";
for my $bg(0..15) {
	print sprintf("%2d : ", $bg);
	$console->Attr($bg << 4);
	print "                              \n";
	$console->Attr($attr); # 初期値にリセット
}

print "\n## 文字色\n";
for my $fg(0..15) {
	print sprintf("%2d : ", $fg);
	$console->Attr($fg);
	print "##############################\n";
	$console->Attr($attr); # 初期値にリセット
}

f:id:AyeBee_TY:20140903201839p:plain

以上。

## 参考