古いがVS2005のMFC(C++)のGUIモードのアプリにて実験。
MFCも土台はWin32なので、以下で、Win32 に起因するような事柄に関しては、Win32 という言葉で説明することがある。
Win32のGUIモードのアプリは、最初は端末画面は存在していないが、AllocConsole() を呼び出せば作る事が出来る。
そして、AllocConsole の文字コード(cp: CodePage)は、今回調べた限り、最初から 932 であったが、CP=932 は、SJIS を表す。
文字コードとは全く無関係の話になるが、この状態では、_cputs や _cprintf はその端末画面に対して機能するが、printf はその端末には接続されていない、したがって、基本事項として、
freopen("CONOUT$", "w+", stdout);
として、新しい端末画面を stdout に接続してから printf しなければならない。
こうすると、_cprintf と printf のどちらも、ASCII コードならば、この端末に出力できるようになる。
一番重要なことは、この状態で、_cprintf では、SJISの日本語が文字化けするが、printf では文字化けしないことである。
理由は不明。
取り急ぎ、メモ。
なお、ソースファイル test.cpp の文字コードは、SJISとして保存している。
AllocConsole();
_cprintf( "Hello\n" );
_cprintf( "GetConsoleOutputCP() = %d\n", GetConsoleOutputCP() ); // 932
_cprintf( "GetConsoleCP() = %d\n", GetConsoleCP() ); // 932
SetConsoleOutputCP( 932 ); // Console の出力文字コードを SJIS に
SetConsoleCP( 932 ); // Console の入力文字コードを SJIS に
_cprintf( "GetConsoleOutputCP() = %d\n", GetConsoleOutputCP() ); // 932
_cprintf( "GetConsoleCP() = %d\n", GetConsoleCP() ); // 932
_cprintf( "_cprintf, Nihongo = 日本語\n" ); // 文字化けする。
freopen("CONOUT$", "w+", stdout); // stdout を console に接続する。
SetConsoleTitle("Debug Console"); // AllocConsole の端末の Window のタイトル文字列を変更できる。
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED); // AllocConsole の端末の中の色を変えられる事を確認した。
printf( "Hello2\n" );
printf( "printf, 1, Nihongo = 日本語\n" ); // 正常に出力され、ちゃんと日本語が見える
SetConsoleOutputCP( 932 );
SetConsoleCP( 932 );
printf( "printf, 2, Nihongo = 日本語\n" ); // 正常に出力され、ちゃんと日本語が見える
_cprintf( "_cprintf, 2, Nihongo = 日本語\n" ); // 文字化けする。
その時に AllocConsole の端末に出力された様子 :
Hello
GetConsoleOutputCP() = 932
GetConsoleCP() = 932
GetConsoleOutputCP() = 932
GetConsoleCP() = 932
_cprintf, Nihongo = ?u?{?e
Hello2
printf, 1, Nihongo = 日本語
printf, 2, Nihongo = 日本語
_cprintf, 2, Nihongo = ?u?{?e