スポンサーリンク

DialogBox関数でリソースからモーダルダイアログを作る

呼び出したら、OKやキャンセルボタンを押すまで処理が返ってこないウィンドウをモーダルダイアログと言う。

1 .リソースを追加する

プロジェクトを右クリック→[追加]→[リソース…]を選択し、リソースの種類(T)で[Dialog]を選択し、[新規作成]ボタンを押すことでリソースを追加する。

 dlg1 → dlg2

 

2.resource.hをインクルードする

#include "resource.h" //IDD_DIALOG1の定義が入っている

 

3.ダイアログプロシージャを記述する

ダイアログプロシージャは普通のウィンドウプロシージャと似ているが、戻り値がINT_PTRとなっている。

この関数では、メッセージを処理した場合はTRUEを、処理しなかった場合はFALSEを返す必要がある。

注意:DefWindowProcで返してはならない。挙動がおかしくなる。

また、モーダルダイアログ呼出中は呼出元は停止しているので、この関数のどこかでEndDialogをしてダイアログを終了しなければならない。

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:
      EndDialog( hWnd , (INT_PTR)IDOK );
      ret = TRUE;
      break;
    case IDCANCEL:
      EndDialog( hWnd , (INT_PTR)IDCANCEL );
      ret =TRUE;
      break;
    }
    break;
  case WM_CLOSE:
    EndDialog( hWnd , (INT_PTR)WM_CLOSE );
    ret =TRUE;
    break;
  }
  return ret;
}

 

4.DialogBox関数を呼び出す

DialogBox関数:https://msdn.microsoft.com/ja-jp/library/cc410759.aspx

第二引数は「ダイアログボックステンプレートの名前(文字列)」か「リソース識別子(数値)」を渡す。後者の場合、MAKEINTRESOURCEで変換する。

第三引数はダイアログを呼び出す親ウィンドウのハンドル(HWND)を渡す。この例では親ウィンドウを作っていないのでNULLを渡す。

INT_PTR d = DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),nullptr,(DLGPROC)DlgWndProc );

 

5.DialogBoxの結果を評価する

DialogBox関数の戻り値は、EndDialog関数の第二引数である。INT_PTRにキャストして正常に返せるのならどんな値でもいいが、用途としてはどのボタンで閉じられたかが思いつく。あるいはダイアログ側で設定したデータを収めた構造体のインスタンスへのポインタなどが良いかもしれない。

  switch(d){
  case IDOK:
    MessageBox(nullptr,_T("IDOK"),0,0);
    break;
  case IDCANCEL:
    MessageBox(nullptr,_T("IDCANCEL"),0,0);
    break;
  case WM_CLOSE:
    MessageBox(nullptr,_T("WM_CLOSE"),0,0);
    break;
  }
  PostQuitMessage(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)
      EndDialog(hWnd, (INT_PTR)IDOK);
      ret = TRUE;
      break;
    case IDCANCEL:
      EndDialog(hWnd, (INT_PTR)IDCANCEL);//ダイアログを閉じる。IDOK,IDCANCELはそれぞれ1と2なので、INT_PTRへキャストできる
      ret = TRUE;
      break;
    }
    break;
  case WM_CLOSE:
    EndDialog(hWnd, (INT_PTR)WM_CLOSE);
    ret = TRUE;//このメッセージを処理したのでTRUEを返す
    break;
  }
  return ret;
}
//エントリーポイント
int WINAPI WinMain(HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  PSTR    lpCmdLine,
  int       nCmdShow)
{
  //ダイアログ表示
  INT_PTR d = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, (DLGPROC)DlgWndProc);

  switch (d) { //ダイアログの戻り値の確認
  case IDOK:
    MessageBox(nullptr, _T("IDOK"), 0, 0);
    break;
  case IDCANCEL:
    MessageBox(nullptr, _T("IDCANCEL"), 0, 0);
    break;
  case WM_CLOSE:
    MessageBox(nullptr, _T("WM_CLOSE"), 0, 0);
    break;
  }
  PostQuitMessage(0);

  return 0;
}

 

 

 

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: