メッセージボックスマスター

さて、前回作ったプログラムはメッセージボックスを表示するプログラムでした。 実行すると以下のようなメッセージボックスが表示されます。 今回は前回作ったこのプログラムを解説します。



前回のソースコードは↓でした。 以下、順番に解説していきます。


#include <windows.h> int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { MessageBox(NULL,"Hello World!","Win32Program",MB_OK); return 0; }



1:#include <windows.h>

これは、「windows.h」というヘッダーファイルをインクルードするということです。 Cランタイムライブラリでは「stdio.h」、C++のIOストリームなら「iostream.h」、そしてWin32APIでは「windows.h」な訳です。 このファイルの中には様々なWin32API関数が宣言されているので、これをインクルードすることによってWin32APIを使うことが出来ます。
知らない人のために書いておくと、インクルードというのはそのファイルをそこに組み込んでしまう、ということです。主にヘッダーファイルを組み込みます。

2:int WINAPI WinMain(...)

ここがメインの部分になります。名前からも分かりますね。「main 関数」のWindows版が「WinMain」にあたります。 全てのWindowsプログラムはこの関数で始まりこの関数で終わります。DOS等と同じように上から下へ流れてゆきます。
さて、ここをみてまず気が付くのは訳の分からない文字がうじゃうじゃ出ているということです。 WINAPI,HINSTANCE,LPSTR,NULLなどなどです。もちろんこれ以外にも大量に存在しますが、全てWindowsが勝手に作った物なのでそんなに悩む必要はありません。 実際はint型などの単純なデータ型です。役割別に分かりやすくするために作ったと思われます。
それではWinMain関数をヘルプで調べてみます。VC++のヘルプで調べるには、調べたい関数に合わせてからF1を押します。


int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // pointer to command line int nCmdShow // show state of window );
hInstance アプリケーションのインスタンスハンドルです。
hPrevInstanceアプリケーションの前のインスタンスのハンドルです。Win32 アプリケーションでは常に NULL です。
lpCmdLine コマンドラインが格納された文字列へのポインタです。プログラム名は含みません。コマンドライン全体は、GetCommandLine 関数で取り出します。
nCmdShow ウィンドウをどのように表示するかの指定が入ります。

さて、これだけを見てもさっぱり分からない人も結構いるはず。実際ここではこの引数は全て使っていません。 ですがこの引数たち、ウィンドウを作るときには必要になります。なのでここでは無視してウィンドウを作るときに改めて説明します。(一度にいろいろ言われても覚え切れませんね(T-T))
さて、今度は一つ跳ばして最後の「return 0;」という行に注目してください。戻り値として0を返していますね。理由は、

戻り値関数が WM_QUIT メッセージを受け取って終了したときは、メッセージの wParam パラメータが持つ終了コードを返してください。
関数がメッセージループに入る前に終了したときは、0 を返してください。

といった具合に説明されています。見ての通りメッセージループはありません。なので0を返しています。 メッセージループについてはもうちょい先で説明しますね。
ん。さて、を連発してることに気がつきました(^_^;)。それはともかくさて、 WinMain関数はこんな具合にWindowsアプリケーションで絶対に必要なものだということが分かればOKです。

3:MessageBox(NULL,"Hello World!","Win32Program",MB_OK);

このAPIは、その名の通りメッセージボックスを表示するAPIです。ヘルプから引用して解説すると、


int MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box );
hWnd 作成するメッセージボックスのオーナーウィンドウを指定します。NULL を指定すると、オーナーウィンドウを持たないメッセージボックスが作成されます。
lpText 表示されるメッセージを文字列で指定します。
lpCaption表示されるタイトルを文字列で指定します。NULLの場合"エラー"と表示されます。
uType メッセージボックスの内容と動作を指定します。フラグを組み合わせて指定します。

つまり、lpTextに表示したいメッセージを入れ、lpCaptionに表示したいタイトルを入れ、uTypeでどんなメッセージボックスにしたいかを指定すれば良いわけです。 前回の場合は、メッセージに「"Hello World!"」、タイトルに「"Win32Program"」を指定していますね。 hWndにはメッセージボックスを呼び出すウィンドウハンドルをいれます。ウィンドウハンドルはウィンドウを作るときに説明しますね。 ではuTypeはほかに何を指定できるのか。やっぱりヘルプから引用してみます。

ボタンのフラグ
フラグ意味
MB_ABORTRETRYIGNORE [ 中止 ]、[ 再試行 ]、[ 無視 ] プッシュボタンを表示します。
MB_OK [OK] プッシュボタンを表示します。デフォルトです。
MB_OKCANCEL [OK]、[ キャンセル ] プッシュボタンを表示します。
MB_RETRYCANCEL [ 再試行 ]、[ キャンセル ] プッシュボタンを表示します。
MB_YESNO [ はい ]、[ いいえ ] プッシュボタンを表示します。
MB_YESNOCANCEL [ はい ]、[ いいえ ]、[ キャンセル ] プッシュボタンを表示します。

さて、ここで初めて「MB_OK」が出てきました!そしてこれが何なのかも分かったと思います。 ここに書いてあるとおりに、いろいろソースコードを変更して試してみてください。いろいろ発見があると思います。 さて、メッセージボックスはこれだけではありません。他にもいろいろあるので全て書いてみようと思います。

アイコンのフラグ
フラグ意味
MB_ICONEXCLAMATION , MB_ICONWARNING 感嘆符アイコンを表示します。
MB_ICONINFORMATION , MB_ICONASTERISK吹き出しの中に小文字の「 i 」があるアイコンを表示します。
MB_ICONQUESTION 疑問符のアイコンを表示します。
MB_ICONSTOP , MB_ICONERROR , MB_ICONHAND停止のアイコンを表示します。

「 , 」で区切ったのは、どちらを使っても同じという意味です。 これを指定すると、アイコンが左の方にくっついてきます。音も変わりますよ。

デフォルトボタンのフラグ
フラグ意味
MB_DEFBUTTON1最初のボタンをデフォルトプッシュボタンにします。デフォルトです。
MB_DEFBUTTON22 番目のボタンをデフォルトプッシュボタンにします。
MB_DEFBUTTON33 番目のボタンをデフォルトプッシュボタンにします。
MB_DEFBUTTON44 番目のボタンをデフォルトプッシュボタンにします。

デフォルトボタンというのは、ちょっと枠が太くなっているアレです。 そのまんまリターンキーを押すとそこが押されるアレですね。

動作形態のフラグ
フラグ意味
MB_APPLMODAL ユーザーは、メッセージボックスに応答しなければ、hWnd パラメータで指定されたウィンドウで作業を継続することはできません。ほかのアプリケーションのウィンドウに移動して作業することはできます。デフォルトです。
MB_SYSTEMMODALメッセージボックスが WS_EX_TOPMOST スタイルを持つ以外は、MB_APPLMODAL と同じです。ユーザーがすぐに気付く必要があるような重大なエラーを通知するために使用します。
MB_TASKMODAL hWnd パラメータが NULL のときに現在のタスクに属するすべてのトップレベルウィンドウが無効になることを除いて、MB_APPLMODAL と同じです。呼び出し側のアプリケーション (またはライブラリ) が有効なウィンドウのハンドルを持っておらず、かつ、ほかのアプリケーションを中断せずに現在のアプリケーションのほかのウィンドウへの入力を禁止したいときに使用します。

ここらへんは意味が分かりませんね。 用は重要なときとかに指定する、といった感じでしょうか。

その他のフラグ
フラグ意味
MB_DEFAULT_DESKTOP_ONLY現在入力を受け取るデスクトップは、デフォルトのデスクトップでなければなりません。それ以外の場合には、関数が失敗します。デフォルトのデスクトップは、ユーザーがログオンした後でアプリケーションが動作するデスクトップです。
MB_HELP[ヘルプ]プッシュボタンを追加します。ユーザーがヘルプボタンを選択したり F1 キーを押したりすると、ヘルプイベントが生成されます。
MB_RIGHTテキストを右寄せします。
MB_RTLREADING右から左へテキストを表示します。ヘブライ語やアラビア語をサポートしているシステムで有効です。
MB_SETFOREGROUNDメッセージボックスをフォアグラウンドウィンドウにします。Windows システムは、内部で SetForegroundWindow 関数を呼び出します。
MB_TOPMOSTメッセージボックスを最前面ウィンドウ (WS_EX_TOPMOST) で作成します。
MB_SERVICE_NOTIFICATIONWindows NT 専用です。呼び出し側がユーザーにイベントを通知するサービスのときに指定します。ユーザーがログオンしていないときも、現在のアクティブなデスクトップにメッセージボックスを表示します。このフラグをセットするときは、hWnd パラメータに NULL を指定してください。
MB_SERVICE_NOTIFICATION_NT3XWindows NT 専用です。この値は、Windows NT バージョン 3.51 で MB_SERVICE_NOTIFICATION として定義された値と同じです。

TOPMOSTとかRIGHTは結構つかえそうですね。

さてと、たくさんありますね(笑)。さらに結構途中に訳の分からないものもあったと思います。奥が深いです。 これを全て覚える訳ではありません。それをやってたらプログラミング組む前に脳が疲れ果てます(^_^;)。 そこでよく使えそうなものを色を変えてみました。これでちょっとは分かりやすいかな。
さぁ、この章の最後です。「戻り値」。さっきもWinMainでやりましたが、今回はさっきよりも複雑です。 なぜならOKが押されたか、CANCELが押されたかなどは戻り値に入っているからです。これを調べれば分かるんですね。

MessageBoxの戻り値
意味
IDABORT [中止]ボタンが選択されました。
IDCANCEL[キャンセル]ボタンが選択されました。
IDIGNORE[無視]ボタンが選択されました。
IDNO [いいえ]ボタンが選択されました。
IDOK [OK]ボタンが選択されました。
IDRETRY [再試行]ボタンが選択されました。
IDYES [はい]ボタンが選択されました。
[キャンセル]ボタンがあるときに[Esc]キーを押すと、IDCANCEL 値が返ります。

ここまで来てピンときた人もいるかもしれません。 今までの知識(たった2ページだけど(^_^;))で、ちょっとしたアドベンチャーゲームがつくれますね。 といっても分岐を続けるだけですが・・・。まぁ何事も工夫です。やろうと思えば何とかなる、これがプログラミングというものです。(多分)

さて、今回のソースコードです。ifで戻り値を判定して振り分けています。


#include <windows.h> int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { int r; // 戻り値チェック用だぞ MessageBox(NULL,"Hello World!","Win32Program",MB_OK); // OKとCANCELを選べるぞ&Questionのアイコンを使ってるぞ r=MessageBox(NULL,"準備はOK?","分岐てすと",MB_OKCANCEL | MB_ICONQUESTION); if(r==IDCANCEL) goto ESCAPE; // キャンセルが押されると"ESCAPE"へいきます。 // 再試行が出るぞ&Informationのアイコンを使ってるぞ r=MessageBox(NULL,"再試行するなら今!" ,"MB_RETRYCANCEL" ,MB_RETRYCANCEL | MB_ICONINFORMATION); if(r==IDCANCEL) goto ESCAPE; // はい、いいえを選べるぞ&Questionのアイコンを使ってるぞ r=MessageBox(NULL,"プログラは好きかな?","MB_YESNO",MB_YESNO | MB_ICONQUESTION); if(r==IDNO) goto ESCAPE; r=MessageBox(NULL,"ほんとに好きかな〜?","MB_YESNOCANCEL",MB_YESNOCANCEL | MB_ICONQUESTION); if(r!=IDYES) goto ESCAPE; // はい以外だと"ESCAPE"へいくぞ。 // 物騒だぞ if(MessageBox(NULL,"重大なエラーです!","嘘だけど",MB_ABORTRETRYIGNORE | MB_ICONSTOP)==IDIGNORE) { MessageBox(NULL,"無視しちゃいやーん",0,0); goto ESCAPE; } // デフォルトボタンのテストだぞ MessageBox(NULL,"1","デフォルトテスト",MB_YESNOCANCEL|MB_HELP|MB_DEFBUTTON1); MessageBox(NULL,"2","デフォルトテスト",MB_YESNOCANCEL|MB_HELP|MB_DEFBUTTON2); MessageBox(NULL,"3","デフォルトテスト",MB_YESNOCANCEL|MB_HELP|MB_DEFBUTTON3); MessageBox(NULL,"4","デフォルトテスト",MB_YESNOCANCEL|MB_HELP|MB_DEFBUTTON4); //このまま下へ行くぞ ESCAPE: MessageBox(NULL,"おわります",0,0); // 省略も可能だぞ return 0; }

少しややこしそうに見えますが、実際はMessageBoxしてから戻り値を判定しているだけです。

DownLoad!サンプルソースファイルをDownLoad!


といったところでひとまず終了です。来週からはWindowsらしく本格的なウィンドウを作ってみます。 難しいですけどがんばってくださいねヽ(^0^)ノではでは・・・


★INDEX★

Copyright(C) へぽぽ