スポンサーリンク

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

ダイアログを作った後、呼び出し元に処理が戻るモーダレスダイアログ(モードレスダイアログ)を作成する。

1 .リソースを追加する

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

 dlg1 → dlg2

 

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

 

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

 

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

ダイアログプロシージャは普通のウィンドウプロシージャと似ているが、戻り値が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;
}

 

4.CreateDialog関数を呼び出す

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;
}

 

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

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


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