018:モーダイルダイアログを作る

モーダルダイアログを作る

今まで、ウィンドウを使ったプログラムを作成してきました。でもちょっとした情報の表示や設定を行いたいだけの場合には、ダイアログが便利です。
また、ダイアログの場合は、VisualC++の「リソースエディタ」を用いて、WYSIWYGにダイアログを作成することが可能ですので、ちょっとしたアプリケーションの作成に向いています。

ダイアログリソースを作成する

まずダイアログリソースの作成を行います。
[ソリューション エクスプローラ]の中の、[リソースファイル]を右クリックします。
メニューから[追加(D)]-[リソース(R)…]を選択します。

このように、正しく表示されました。

なぜダイアログではこのような事が起こるのでしょう。実はダイアログではフォントのサイズを基にして、ダイアログの幅、高さ、オブジェクトの幅、高さを決めているのです。ダイアログにデフォルトで設定されているフォント "MS Shell Dlg"がWindowsMobileには存在しないため、ダイアログやオブジェクトの幅が正しく設定されず、文字が切れたり、チェックボックスラジオボタンの上下が切れてしまったのです。

ダイアログボックスには、今回作成したモーダルダイアログボックスの他に、モードレスダイアログボックスというものがあります。

モーダルダイアログボックス ダイアログボックスを閉じるまで、他の操作が出来ません。通常のアプリケーションではよくこれを使いますね。
モードレスダイアログボックス ダイアログボックスを開いている間にも他の操作が出来ます。ダイアログボックスを開いたまま、ブラウザを開いたり、電卓を開いたりすることができます。Excelの検索ダイアログがこれにあたりますね。Excelでは検索ダイアログを開いたまま操作ができますよね。

 
 

では、今回のプログラムの説明です。

モーダルダイアログを作るには、DialogBox関数を呼び出します。ダイアログボックスを閉じるときにはEndDialog関数を呼び出します。

DialogBox関数
モーダルダイアログを表示します。

int DialogBox(
  HINSTANCE
hInstance,      // インスタンスハンドル
  LPCTSTR lpTemplate,       // ダイアログボックステンプレート
  HWND hWndParent,          // 親ウィンドウのハンドル
  DLGPROC lpDialogFunc      // ダイアログプロシージャのポインタ
);

EndDialog関数
モーダルダイアログボックスを破棄し、そのダイアログボックスに関係するすべての処理を終了します。

BOOL EndDialog(
  HWND
hDlg,        // ダイアログボックスのハンドル
  INT_PTR nResult   // 返したい値
);

WinMain関数を見てください。今までのプログラムとは違い、メッセージループがありません。これは、DialogBox関数の処理はEndDialog関数が呼び出されるまで終了しないためです。

DialogBox関数のlpTemplateにはダイアログリソースを指定します。リソース識別子を指定する場合、上位ワードに 0 を、下位ワードに識別子を指定しなければなりません。MAKEINTRESOURCEマクロを使用すれはリソース識別子を作成できます。

lpDialogFuncにはダイアログプロシージャを指定します。

ダイアログプロシージャDlgProcを見てみましょう。ダイアログでは、ボタンが押されるなどのイベントが発生すると、WM_COMMANDメッセージが届きます。これだけでは、どのボタンが押されたのかわかりませんね。追加の情報がwParamに格納されています。どのボタンか判断するにはLOWORD(wParam)とします。これで押されたボタンのIDがわかります。
LOWORDは特定の値の下位ワードを取り出すマクロです。つまりwParamの下位ワードに押されたボタンのIDが格納されているのです。

サンプルでは、IDOKとIDCANCELの処理を別々に書いていますが、ダイアログプロシージャの中での処理が特にない場合はまとめて下のように書きます。EndDialogの第2引数にLOWORD(wParam)を指定するのがポイントです。

        switch( LOWORD(wParam) ) {
        case IDOK:
        case IDCANCEL:
            EndDialog(hDlg,LOWORD(wParam));
            break;
        }

今日はここまでです。

上部へスクロール