メッセージボックス

メッセージボックスの表示

今回はメッセージボックスを表示させてみましょう。メッセージボックスの表示は以前にもAPI関数呼び出しの例としてやっていますが、ここではより細かい設定なども行ってみたいと思います。

以前にやったように、メッセージボックスの表示にはMessageBox関数を使います。

int MessageBoxA(
    HWND   hWnd,       // owner window handle
    PCTSTR pszText,    // message string
    PCTSTR pszCaption, // title string
    UINT   uType       // type
);

まず、最初のhWndパラメータには、オーナーウィンドウのハンドルを指定します。オーナーウィンドウというのは、表示するメッセージボックスを「所有する」ウィンドウのことです。すなわち、メッセージボックスの持ち主をどのウィンドウにするかということです。ここで指定されたウィンドウは、メッセージボックスが表示されている間は停止された状態になり、ウィンドウの操作もできなくなります。このパラメータに0 (NULL) を指定することによってオーナーウィンドウを持たないメッセージボックスを表示させることもできます。今回は、このパラメータに、現在の描画先のウィンドウハンドルであるシステム変数hwndを指定しましょう。

次に、2番目のpszTextパラメータと3番目のpszCaptionパラメータには、それぞれ、メッセージボックスの内部に表示する文字列のアドレスとキャプションバー(タイトルバー)に表示する文字列のアドレスを指定しなければなりません。これについては、#funcによる関数定義の引数型指定でこれらのパラメータにsptrを指定しておくことで、文字列を直接指定することができるというのは以前に説明したとおりです。

3番目のpszCaptionパラメータには、タイトル文字列のアドレスの代わりに、0 (NULL) を指定することもできます。この場合には、「エラー」というタイトル文字列が表示されることになります。

最後のuTypeパラメータには、表示するメッセージボックスの種類を指定します。例えば、[OK][キャンセル]ボタンを持つメッセージボックスの場合には、1 (MB_OKCANCEL) を指定します。その他にも、以下の種類が存在します。

定数名 ボタンの種類
MB_OK 0x00000000 [OK]
MB_OKCANCEL 0x00000001 [OK][キャンセル]
MB_ABORTRETRYIGNORE 0x00000002 [中止][再試行][無視]
MB_YESNOCANCEL 0x00000003 [はい][いいえ][キャンセル]
MB_YESNO 0x00000004 [はい][いいえ]
MB_RETRYCANCEL 0x00000005 [再試行][キャンセル]

これらの数字だけでは文字列とボタンしか表示されませんが、別の値を組み合わせることでアイコンを表示させることもできます。例えば、0x30 (MB_ICONEXCLAMATION) を組み合わせて指定することで感嘆符「!」のアイコンを表示させることができます。そのほかのアイコンは、以下の値で表示させることができます。

定数名 アイコンの種類
MB_ICONSTOP 0x00000010 停止のアイコン
MB_ICONQUESTION 0x00000020 疑問符のアイコン
MB_ICONEXCLAMATION 0x00000030 感嘆符のアイコン
MB_ICONINFORMATION 0x00000040 吹き出しに「i」のアイコン

知らない方のために説明しておきますと、0x30の「0x」というのは、その値が16進数表示であることを表しています。これはHSPで「$30」と記述したのとまったく同じ意味になります。HSPではどちらの表記法でも使うことができますが、このドキュメントでは主に「0x」の表記を使用しています。

ここで、「値を組み合わせて指定する」と説明しましたが、API関数の引数ではこのように値を組み合わせて指定するパラメータが非常に多く存在します。このuTypeパラメータもその1つです。この場合には、それぞれの値の論理和(OR結合)をとった値を指定します。つまり、ビット演算子「|」で結びつけた値を指定するということです。例えば、MessageBox関数で、[OK][キャンセル]ボタンと感嘆符「!」のアイコンを表示したメッセージボックスを表示するには、uTypeパラメータに1 | 0x30(すなわち0x31)を指定することになります。ただし、実際のスクリプトでは直接0x31という値を記述するのではなく、定数名を#defineまたは#constで定義しておいてから使用するほうが分かりやすくてよいと思います。

この関数は、呼び出した後の戻り値から、どのボタンが押されたのかを知ることができます。どのような値が返されるかは、表示されたメッセージボックスによって異なります。例えば、[OK]が押されると1が、[キャンセル]が押されると2が返されます。そのほか、押されたボタンによって、以下の戻り値になります。

定数名 ボタンの種類
IDOK 1 OK
IDCANCEL 2 キャンセル
IDABORT 3 中止
IDRETRY 4 再試行
IDIGNORE 5 無視
IDYES 6 はい
IDNO 7 いいえ

これらの戻り値はシステム変数statに格納されているので、その値を調べて判断します。

サンプルスクリプト

以下のスクリプトは、[OK][キャンセル]ボタンを表示させてどのボタンが押されたのかを表示するスクリプトです。MessageBox関数の第2、第3パラメータは文字列のアドレスを渡しますが、先ほど述べたとおり、sptr型指定を用いるので、ここでは文字列(変数)を直接指定することができます。もちろん、varptrを使って文字列変数のアドレスを指定することもできます。

; 関数の定義
#uselib "user32.dll"
#func MessageBox "MessageBoxA" int, sptr, sptr, int

; 定数名の定義
#define MB_OKCANCEL         0x00000001
#define MB_ICONEXCLAMATION  0x00000030
#define IDOK                0x00000001

; 関数の呼び出し
msgTitile = "メッセージボックスのテスト"
msgText = "フリープログラミング言語 Hot Soup Processor"
MessageBox hwnd, msgText, msgTitile, MB_OKCANCEL | MB_ICONEXCLAMATION

; 戻り値から押されたボタンを判断
if (stat == IDOK) {
    dialog "[OK]ボタンが押されました"
} else {
    dialog "[キャンセル]ボタンが押されました"
}
end

感嘆符のアイコンとともに、[OK][キャンセル]ボタンが表示されます。ボタンを押してメッセージボックスを閉じると、どちらのボタンが押されたのかを、再びメッセージボックス(こちらはdialog命令)で表示しています。ちなみに、右上の[×]ボタンやエスケープキーによって閉じると、[キャンセル]が押されたものと判断されます。