モーダレスダイアログボックスを作成する関数には、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("鵺") ); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
#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