Tips of VC++ > ダイアログ > モーダレスダイアログボックスを作る
前へ戻る次へ進む


モーダレスダイアログボックスを作る

モードレスダイアログとは他のウィンドウにフォーカスを移すことのできるダイアログです。 メモ帳の検索ダイアログなどがそうです。 これはモーダルダイアログよりも少し面倒で、メッセージループを作らなければなりません。 よって、ソースはウィンドウに似てきます。

HWND CreateDialog(
  HINSTANCE hInstance,  // モジュールのハンドル
  LPCTSTR lpTemplate,   // ダイアログボックステンプレートの名前
  HWND hWndParent,      // オーナーウィンドウのハンドル
  DLGPROC lpDialogFunc  // ダイアログボックスプロシージャ
);

これはマクロです。実際はCreateDialogParamを呼びますが、 パラメータが1個多くてダイアログの初期データを送る事ができるだけです。 必要に応じて使ってください。
では、ダイアログベースのプログラムを モードレスダイアログバージョンで書きます。

const char szClassName[]="アプリケーション名";

LRESULT CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow )
{
    HWND hDlg=::CreateDialog(hAppModule,MAKEINTRESOURCE(IDD_DIALOG1),
        NULL,(DLGPROC)DlgProc);
    ::ShowWindow(hDlg,SW_SHOW);

    MSG msg;
    while ( ::GetMessage(&msg,NULL,0,0) )
    {
        if ( !::IsDialogMessage(hDlg,&msg) )
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
    }
    return 0;
}

LRESULT CALLBACK DlgProc(HWND in_hWnd,
                         UINT in_Message,
                         WPARAM in_wParam,
                         LPARAM in_lParam)
{
    switch ( in_Message )
    {
    case WM_COMMAND:
        switch ( LOWORD(in_wParam) )
        {
        case IDCANCEL:
            ::DestroyWindow(in_hWnd);
            break;
        }
        break;
    case WM_DESTROY:
        ::PostQuitMessage(0);
        break;
    }
    return 0;
}

メッセージループが少し違いますね。 次のようなAPIを呼び出しています。

BOOL IsDialogMessage(
  HWND hDlg,   // ダイアログボックスのハンドル
  LPMSG lpMsg  // チェックしたいメッセージ
);

このAPIは、lpMsgをチェックして、 ダイアログ宛てのものだった場合はDispatchMessageと同じ働きをして、 メッセージをプロシージャに送信します。 その場合はTranslateMessageやDispatchMessageに渡してはならないので、 if文で判定しているわけです。
メッセージを処理するとき、この関数はキーボードメッセージを調べて、 それに対応するダイアログボックスの選択コマンドへ変換します。 たとえば、Tab キーが押されると、次のコントロールまたは 次のコントロールグループを選択します。 また、[↓]キーが押されると、グループ内の次のコントロールを選択します。 そのため、この関数を呼び出さないとTabキーを押してもフォーカスが写らなくなります。