ちょっと間が空いてしまいましたが、連載第2回です。
今回は、前回作ったメッセージ リソースを使うコードを紹介します。
前回までで、以下のようなプロジェクトができているはずです。
これに、ソース ファイルを追加しましょう。
ファイル名は MsgRes.cpp とでもしておきます。
で、いきなりですが中身を公開します。
#include <windows.h>
#include <stdio.h>
#include <locale.h>
#include <tchar.h>
#include "MsgRes.h"
int _tmain()
{
setlocale( LC_CTYPE, "japanese" );
LPTSTR msg = NULL;
DWORD result = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, MSGID_SAMPLE_0001, MAKELANGID( LANG_JAPANESE, SUBLANG_DEFAULT ),
reinterpret_cast< LPTSTR >( &msg ), 0, NULL );
if( result != 0 )
{
_putts( msg );
LocalFree( msg );
}
setlocale( LC_CTYPE, "english" );
result = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, MSGID_SAMPLE_0001, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ),
reinterpret_cast< LPTSTR >( &msg ), 0, NULL );
if( result != 0 )
{
_putts( msg );
LocalFree( msg );
}
return 0;
}
はい。みんな大好き FormatMessage です。
GetLastError が返すエラーコードを文字列化するのにしか使ったことがない方も少なくないと思います。
今回は、第一引数に FORMAT_MESSAGE_FROM_HMODULE を指定し、第二引数に NULL を指定しています。
この場合、呼び出し側プロセスの EXE モジュールのハンドルを指定したのと同じことになります。
MSGID_SAMPLE_0001 は、前回 MsgRes.mc で定義し、メッセージ コンパイラによって MsgRes.h に書かれているメッセージ識別子です。
続いて言語識別子を指定しています。これは MsgRes.mc の LanguageNames で指定した値です。
言語識別子を変えることで、同じメッセージ識別子でも違うメッセージが取得できているのが分かると思います。
本題は以上です。以下、ちょっとしたオマケ。
メッセージ コンパイラが生成した MsgRes.rc を開いてみると、以下のような、なんともそっけないコードになっています。
LANGUAGE 0x11,0x1
1 11 "MSG_JA.bin"
LANGUAGE 0x9,0x1
1 11 "MSG_EN.bin"
これでは何だかわからん! という方のために、もう少し読みやすく書き換えてみます。
ただし、このファイルはもう一度メッセージ コンパイラを実行すれば上書きされてしまうので、別のリソース ファイルを作りましょう。
MsgRes.rc を一旦プロジェクトから除外し、新しいリソース スクリプトを MsgRes2.rc とでも名づけて作成しましょう。
そうしたら、リソース ビューで MsgRes2.rc を右クリックして「リソース ファイルのインクルード」を選択します。
出てきたダイアログに、以下のように入力しましょう。
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
1 MESSAGETABLE "MSG_JA.bin"
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
1 MESSAGETABLE "MSG_EN.bin"
これで、言語も、メッセージ リソースだということもわかりやすくなりますね。
ただし、リソース コンパイラは MESSAGETABLE というキーワードを理解しますが、Visual C++ のリソースエディタは理解しません。
というかそれ以前に、このダイアログで入力した内容は、リソース ビューに表示されません。
このダイアログを使わずに、MsgRes2.rc を直接書き換えても、リソースの種類は "11" と表示されるだけです。ちょっとさみしいですね。
次回は、挿入シーケンスの使い方と、エラー コードに対するメッセージを定義する方法を解説します。