スポンサーリンク
ダイアログを作った後、呼び出し元に処理が戻るモーダレスダイアログ(モードレスダイアログ)を作成する。
プロジェクトを右クリック→[追加]→[リソース...]を選択し、リソースの種類(T)で[Dialog]を選択し、[新規作成]ボタンを押すことでリソースを追加する。
#include "resource.h"//IDD_DIALOG1の定義が入っている
ダイアログプロシージャは普通のウィンドウプロシージャと似ているが、戻り値がINT_PTRとなっている。
この関数では、メッセージを処理した場合はTRUEを、処理しなかった場合はFALSEを返す必要がある。
注意:DefWindowProcで返してはならない。挙動がおかしくなる。
モーダルダイアログの時と概ね同じだが、ウィンドウの破棄には(EndDialogではなく)DestroyWindowを使う。下コードではPostQuitMessageもしているが、これはこのサンプルの都合である。
INT_PTR CALLBACK DlgWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { INT_PTR ret = FALSE; switch (msg) { case WM_COMMAND: switch (wp) { case IDOK: MessageBox(hWnd, _T("IDOK"), 0, 0); DestroyWindow(hWnd); PostQuitMessage(0); ret = TRUE; break; case IDCANCEL: MessageBox(hWnd, _T("IDCANCEL"), 0, 0); DestroyWindow(hWnd); PostQuitMessage(0); ret = TRUE; break; } break; case WM_CLOSE: DestroyWindow(hWnd); PostQuitMessage(0); ret = TRUE; break; } return ret; }
CreateDialog関数 https://msdn.microsoft.com/ja-jp/library/cc410690.aspx
第二引数は「ダイアログボックステンプレートの名前(文字列)」か「リソース識別子(数値)」を渡す。後者の場合、MAKEINTRESOURCEで変換する。
第三引数はダイアログを呼び出す親ウィンドウのハンドル(HWND)を渡す。この例では親ウィンドウを作っていないのでNULLを渡す。
CreateDialog関数は、DialogBox関数と違い、ダイアログを表示した後すぐにウィンドウハンドルを返しに戻ってくる。
そのため、すぐにプログラムが終了しないようにメッセージループに入っている。上記ダイアログプロシージャの中でPostQuitMessageをしているのは、ダイアログが閉じたときに本体も終了させないと、終了させる手段がなくなってしまうからだ。
ちなみにこの関数で作成したダイアログは初期状態で非表示なので、ShowWindowを使って表示させる必要がある。
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { HWND hDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, (DLGPROC)DlgWndProc); ShowWindow(hDlg, SW_SHOW); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
#include <Windows.h> #include "resource.h" //IDD_DIALOG1の定義が入っている #include <tchar.h> //ダイアログプロシージャ INT_PTR CALLBACK DlgWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { INT_PTR ret = FALSE; switch (msg) { case WM_COMMAND://ボタンが押された場合、WM_COMMANDのwParamにボタンのIDが入っている switch (wp) { case IDOK://IDOK(値1),IDCANCEL(値2)は初めから定義されている(WinUser.h) MessageBox(hWnd, _T("IDOK"), 0, 0); DestroyWindow(hWnd);//ダイアログを閉じる。(プログラム終了ではない。それは下のPostQuitMessageがやっている) PostQuitMessage(0); ret = TRUE; break; case IDCANCEL: MessageBox(hWnd, _T("IDCANCEL"), 0, 0); DestroyWindow(hWnd); PostQuitMessage(0);//プログラム終了 ret = TRUE; break; } break; case WM_CLOSE: DestroyWindow(hWnd); PostQuitMessage(0); ret = TRUE; break; } return ret; } //エントリーポイント int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { HWND hDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, (DLGPROC)DlgWndProc); ShowWindow(hDlg, SW_SHOW); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }