メッセージボックスを表示させてみる

メッセージボックス

今回はメッセージボックスを表示させてみましょう。前回も出てきましたが、メッセージボックスといっても、HSPオブジェクトのメッセージボックスではありません。HSPのdialog命令で表示されるあのウィンドウです。Win32 APIを使うとdialog命令では表示できないメッセージボックスも表示させることができるようになります。

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

int MessageBoxA(
    HWND   hWnd,       // オーナーウィンドウのハンドル
    PCTSTR pszText,    // 表示文字列のアドレス
    PCTSTR pszCaption, // キャプションバーの表示文字列のアドレス
    UINT   uType       // メッセージボックスのタイプ
);

この関数は引数として文字列のアドレスを渡していますから、関数名の最後には"A"が付けられています。これを忘れないようにしなければいけません。

最初の引数(hWndパラメータ)には、オーナーウィンドウのハンドルを指定します。オーナーウィンドウというのは、表示するメッセージボックスを「所有する」ウィンドウのことです。メッセージボックスの持ち主をどのウィンドウにするかということです。ここで指定されたウィンドウは、メッセージボックスが表示されている間は停止された状態になり、ウィンドウの操作もできなくなります。

このパラメータに0を指定してオーナーウィンドウを持たないメッセージボックスを作成することもできますが、今回はHSPウィンドウを指定することにします。HSPウィンドウのハンドルは、BMSCR構造体に格納されているので、mref命令で取得することができます。

BMSCR構造体については、『構造体』の項を参照してください。

; 描画中ウィンドウのハンドルを取得
mref bmscr, 67           ; ウィンドウのBMSCR構造体を変数 bmscr に割り当てる
prm.0 = bmscr.13         ; 最初のパラメータにウィンドウハンドルを指定

次に、2番目と3番目の引数(pszTextパラメータとpszCaptionパラメータ)には、メッセージボックスの内部に表示する文字列のアドレスと、キャプションバー(タイトルバー)に表示する文字列のアドレスを指定します。

; メッセージボックスに表示させる文字列
text1 = "フリープログラミング言語 Hot SoupProcessor"
text2 = "メッセージボックスのテスト"
; 2,3番目のパラメータに文字列のアドレスを指定
getptr prm.1, text1
getptr prm.2, text2

最後の引数(uTypeパラメータ)には、表示するメッセージボックスの種類を指定します。例えば、[OK][キャンセル]ボタンを持つメッセージボックスの場合には、1MB_OKCANCELと定義されている)を指定します。また、[はい][いいえ][キャンセル]ボタンを持たせるには3 (MB_YESNOCANCEL) を指定します。

そのほか、表示させるアイコンの種類なども選ぶことができて、例えば、0x30 (MB_ICONEXCLAMATION) を組み合わせて指定することで感嘆符「!」のアイコンを表示させることができますし、0x40 (MB_ICONINFORMATION) を組み合わせて指定することで、吹き出しに「i」マークのアイコンを表示させることもできます。

知らない方のために説明しておきますと、0x30の「0x」というのは、その値が16進数を示すということを表します。これはHSPで「$30」と記述したのとまったく同じ意味になります。HSPではどちらの表記法を使うこともできますが、このページでは「0x」を使うことが多いと思いますので、了承しておいてください。

ここで1つ注意しておくことは、API関数の引数ではよく「値を組み合わせて指定する」というものが出てきます。MessageBox関数のuTypeパラメータもその1つです。この場合には、それぞれの値の論理和(OR結合)をとった値を指定します。つまり、演算子「|」で結びつけた値を指定するということです。例えば、MessageBox関数で、[OK][キャンセル]ボタンと感嘆符「!」のアイコンを表示したメッセージボックスを表示するには、uTypeパラメータに1 | 0x30(すなわち0x31)を指定することになります。

API関数のパラメータとして指定するために演算子「|」で結びつけた値は、一般的にはそれらの値を足し合わせたものと等しくなります。しかし、場合によっては単純に和をとった場合とは値が異なってしまう場合もありますから、できるだけ論理演算を行なうようにして下さい。

; 4番目のパラメータにメッセージボックスの種類
prm.3 = 1 | 0x30         ; MB_OKCANCEL | MB_ICONEXCLAMATION

この関数は、呼び出した後の戻り値から、どのボタンが押されたのかを知ることができます。どのような値が返されるかは、表示されたメッセージボックスによって異なります。[OK][キャンセル]ボタンを持つメッセ―ボックスでは、[OK]が押されると1が、[キャンセル]が押されると2が返されます。これらは変数hspdllおよびシステム変数statに格納されているので、このうちのどちらかを調べて判断します。

サンプルスクリプト

以下のスクリプトは、[OK][キャンセル]ボタンを表示させてどのボタンが押されたのかを表示するスクリプトです。

サンプルスクリプト main.as

    #include "llmod.as"

    ; 描画中ウィンドウのハンドルを取得
    mref bmscr, 67           ; ウィンドウのBMSCR構造体を変数 bmscr に割り当てる
    prm.0 = bmscr.13         ; 最初のパラメータにウィンドウハンドルを指定

    ; メッセージボックスに表示させる文字列
    text1 = "フリープログラミング言語 Hot Soup Processor"
    text2 = "メッセージボックスのテスト"
    ; 2,3番目のパラメータに文字列のアドレスを指定
    getptr prm.1, text1
    getptr prm.2, text2

    ; 4番目のパラメータにメッセージボックスの種類
    prm.3 = 1 | 0x30         ; MB_OKCANCEL | MB_ICONEXCLAMATION

    ; 関数の呼び出し
    dllproc "MessageBoxA", prm, 4, D_USER

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

    end