スポンサーリンク

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

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

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

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

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

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

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

#include <Windows.h>
#include "resource.h"
#include <tchar.h>
INT_PTR CALLBACK WndProcModeless(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message) {
  case WM_INITDIALOG:
    if (lParam) {
      TCHAR* c = (TCHAR*)lParam;
      MessageBox(hWnd, c, 0, 0);
      ShowWindow(hWnd, SW_SHOW);
    }
    return TRUE;
  case WM_COMMAND:
    switch (wParam) {
    case IDOK:
      MessageBox(hWnd, _T("IDOK"), 0, 0);
      PostQuitMessage(0);
      return TRUE;
    }
    return FALSE;
  }
  return FALSE;
}
int WINAPI WinMain(
  HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  PSTR  lpCmdLine,
  int   nCmdShow)
{

  CreateDialogParam(
    hInstance,
    MAKEINTRESOURCE(IDD_DIALOG1),
    nullptr,
    WndProcModeless,
    (LPARAM)_T("鵺")//このパラメータがWM_INITDIALOGのlParamへ入る
  );
  
  MSG msg;
  while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return 0;
}

 

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

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

 

これを使えば、CreateWindow関数の時と同様に、CreateDialogのモードレスダイアログをカプセル化できる。考え方はCreateWindowの時と同じだ。


CnuDlgModeless.h
#pragma once
#include <windows.h>
class CnuDlgModeless {
  HWND m_hwnd;
  HINSTANCE m_hInstance;

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

  virtual ~CnuDlgModeless();

  //CreateDialogParam関数の呼び出し
  HWND nuCreateDialog(
    HINSTANCE hInstance, // インスタンスハンドル 
    LPCTSTR lpTemplate,  // ダイアログボックスの名前
    HWND hWndParent     // 親ウィンドウのハンドル
  );

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

CnuDlgModeless.cpp

#include "CnuDlgModeless.h"

CnuDlgModeless::~CnuDlgModeless() {
}

//CreateDialogParam関数の呼び出し
HWND CnuDlgModeless::nuCreateDialog(
  HINSTANCE hInstance, // インスタンスハンドル 
  LPCTSTR lpTemplate,  // ダイアログボックスの名前
  HWND hWndParent     // 親ウィンドウのハンドル
) {
  m_hInstance = hInstance;
  m_hwnd = CreateDialogParam(GetHInstance(), lpTemplate, hWndParent, (DLGPROC)CnuDlgModeless::StaticWndProcDlg, (LPARAM)this);
  return m_hwnd;
}

//このクラスで作成したモーダルダイアログの全てのイベントが入ってくるダイアログプロシージャ
INT_PTR CALLBACK CnuDlgModeless::StaticWndProcDlg(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  CnuDlgModeless* This = (CnuDlgModeless*)GetWindowLongPtr(hWnd, GWLP_USERDATA);;
  if (message == WM_INITDIALOG) {
    if (lParam) {
      This = (CnuDlgModeless*)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);
}

INT_PTR CnuDlgModeless::WndProcDlg(
  HWND hWnd,
  UINT msg,
  WPARAM wp,
  LPARAM lp
) {
  BOOL ret = FALSE;
  switch (msg)
  {
  case WM_INITDIALOG:
    ShowWindow(hWnd, SW_SHOW);
    ret = TRUE;
    break;
  case WM_CLOSE:
    DestroyWindow(hWnd);
    ret = TRUE;
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    ret = TRUE;
    break;
  }
  return ret;
}

 

main.cpp

#include <Windows.h>
#include "resource.h"
#include <tchar.h>
#include "CnuDlgModeless.h"
class CnuDlgModeless_special : public CnuDlgModeless {
  //CnuDlgModalからオーバーライド。このために親クラスでvirtual指定をしている
  INT_PTR WndProcDlg(
    HWND hWnd,
    UINT msg,
    WPARAM wp,
    LPARAM lp
  ) {
    BOOL ret = FALSE;
    switch (msg)
    {
    case WM_INITDIALOG:
      ShowWindow(hWnd, SW_SHOW);
      ret = TRUE;
      break;
    case WM_CLOSE:
      DestroyWindow(hWnd);
      ret = TRUE; 
      break;
    case WM_DESTROY:
      ret = TRUE; 
      PostQuitMessage(0);
      return 0;
    }
    return ret;
  }
};

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

  CnuDlgModeless_special modelesssp;
  modelesssp.nuCreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr);

  MSG msg;
  while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return 0;
}

 

CnuDlgModeless.zip

CnuDlgModeless

コメントを残す

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

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


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