スポンサーリンク

DialogBoxParamでモーダルダイアログボックスをカプセル化する

モーダルダイアログボックスを作成する関数には、DialogBoxの他にDialogBoxParamがある。

https://msdn.microsoft.com/ja-jp/library/cc410761.aspx

int DialogBoxParam(
  HINSTANCE hInstance,  // アプリケーションのインスタンスのハンドル
  LPCTSTR lpTemplateName,  // ダイアログボックステンプレートを指定します
  HWND hWndParent,      // オーナーウィンドウのハンドル
  DLGPROC lpDialogFunc, // ダイアログボックスプロシージャへのポインタ
  LPARAM dwInitParam    // 初期値
);

 

この初期値と呼ばれる第五引数dwInitParamは何かというと、ダイアログ初期化の際に呼ばれるWM_INITDIALOGのlParam値である。

オブジェクト指向ではないDialogBoxにとって、DialogBoxに渡せる、ユーザが任意に指定できるグローバル変数以外の唯一のパラメータがこれなのである。

以下はこのdwInitParamで初期値を渡す例である:

#include <Windows.h>
#include "resource.h"
#include <tchar.h>
//ダイアログプロシージャ
INT_PTR CALLBACK WndProcModal(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message) {
  case WM_INITDIALOG:
    if (lParam) {
      TCHAR* c = (TCHAR*)lParam;
      MessageBox(hWnd, c, 0, 0);
    }
    return TRUE;
  case WM_COMMAND:
    switch (wParam) {
    case IDOK:
      MessageBox(hWnd, _T("IDOK"), 0, 0);
      EndDialog(hWnd, 0);
      return TRUE;
    }
    return FALSE;
  }
  return FALSE;
}
//エントリーポイント
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow)
{
  DialogBoxParam(
    hInstance, 
    MAKEINTRESOURCE(IDD_DIALOG1), 
    nullptr, 
    WndProcModal,
    (LPARAM)_T("鵺")//このパラメータがWM_INITDIALOGのlParamへ入る
  );
  return 0;
}

 

要はCreateWindow関数の第十一引数lpParam「ウィンドウ作成データ」と同じ性質の物だと思えばいい。

https://msdn.microsoft.com/ja-jp/library/cc410713.aspx

 

これを使えば、CreateWindow関数の時と同様に、DialogBoxをカプセル化できる。考え方はCreateWindowの時と同じだ。

CnuDlgModal.h

#pragma once
#include <windows.h>
class CnuDlgModal{
  INT_PTR m_dlg;//DialogBoxの戻り値
  HINSTANCE m_hInstance;

  //このクラスで作成したモーダルダイアログの全てのイベントが入ってくるダイアログプロシージャ
  static INT_PTR CALLBACK StaticWndProcDlg(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
public:
  HINSTANCE GetHInstance()const { return m_hInstance; }
  
  virtual ~CnuDlgModal() {}

  //DialogBoxParam関数の呼び出し
  INT_PTR nuDialogBox(
    const HINSTANCE hInst,
    LPCTSTR lpTemplate,
    HWND hWndParent
  );

  //個別のウィンドウプロシージャ
  virtual INT_PTR WndProcDlg(
    HWND hWnd,
    UINT msg,
    WPARAM wp,
    LPARAM lp
  );
};

 

 

CnuDlgModal.cpp

#include "CnuDlgModal.h"
//このクラスで作成したモーダルダイアログの全てのイベントが入ってくるダイアログプロシージャ
INT_PTR CALLBACK CnuDlgModal::StaticWndProcDlg(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  CnuDlgModal* This = (CnuDlgModal*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  if (message == WM_INITDIALOG) {
    if (lParam) {
      This = (CnuDlgModal*)lParam;
      SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)This);
      return This->WndProcDlg(hWnd, message, wParam, lParam);
    }
  }
  else if (This == 0) {
    return FALSE;
  }
  return This->WndProcDlg(hWnd, message, wParam, lParam);
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//DialogBoxParam関数の呼び出し
INT_PTR CnuDlgModal::nuDialogBox(
  const HINSTANCE hInst,
  LPCTSTR lpTemplate,
  HWND hWndParent
) {
  m_hInstance = hInst;
  m_dlg = DialogBoxParam(GetHInstance(), lpTemplate, hWndParent, (DLGPROC)CnuDlgModal::StaticWndProcDlg, (LPARAM)this);
  return m_dlg;
}
//個別のウィンドウプロシージャ
INT_PTR CnuDlgModal::WndProcDlg(
  HWND hWnd,
  UINT msg,
  WPARAM wp,
  LPARAM lp
) {
  switch (msg)
  {
  case WM_CLOSE:
    EndDialog(hWnd, 0);
    PostQuitMessage(0);
    return TRUE;
  }
  return FALSE;
}

 

 

main.cpp

#include <Windows.h>
#include "resource.h"
#include <tchar.h>
#include "CnuDlgModal.h"
//モーダルダイアログを扱うクラス
class CnuDlgModal_special :public CnuDlgModal {

  //CnuDlgModalからオーバーライド。このために親クラスでvirtual指定をしている
  INT_PTR WndProcDlg(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) override{
    switch (msg)
    {
    case WM_COMMAND:
      switch (wp) {
      case IDOK:
        EndDialog(hWnd, 100);
        return TRUE;
      }
      return FALSE;
    case WM_CLOSE:
      EndDialog(hWnd, 0);
      return TRUE;
    }
    return FALSE;
  }
};

///////////////////////////////////////////////////////
//エントリーポイント////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  PSTR    lpCmdLine,
  int       nCmdShow)
{

  CnuDlgModal_special modalsp;//新たなモーダルダイアログを定義

  modalsp.nuDialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr);//ダイアログ作成・待機
  PostQuitMessage(0);

  return 0;
}

 

CnuDlgModal.zip

CnuDlgModal

コメントを残す

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

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


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