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キーを押してもフォーカスが写らなくなります。