こんにちは。
staticのWndProc側でチョッとした処理をした後、メンバ関数版のWndProcに転送します。
WM_NCCREATEでthisポインタを受け取ったら、ウィンドウに関連付けて使い、WM_NCDESTROY辺りでthisポインタを切り離して削除します。
その他、メンバ関数のWndProc内で処理した上、DefWindowProcに「渡す・渡さない」を決めさせたりする必要があるかもしれません。結構大変です。
大分あるアラがあると思いますが、参考程度に。
struct CMessage
{
template<class _WPARAM, class _LPARAM>
CMessage(HWND h, UINT u, _WPARAM wp, _LPARAM lp)
: hWnd(h), uMsg(u), wParam((WPARAM)wp), lParam((LPARAM)(lp)), bHandled(FALSE)
{ }
union
{
HWND hWnd;
HWND hDlg;
HWND hCtl;
};
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
BOOL bHandled;//WndProc内でココにTRUEを入れるとDefWindowProcを呼ばない。
};
struct CWnd
{
//こっちがコールバック
static LRESULT CALLBACK StaticProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWnd* pWnd = static_cast<CWnd*>(::GetProp(hWnd, TEXT("window ptr")));
CMessage msg(hWnd, uMsg, wParam, lParam);
LRESULT lResult = FALSE;
//初回登録
if(uMsg == WM_NCCREATE)
{
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
pWnd = static_cast<CWnd*>(lpcs->lpCreateParams);
::SetProp(hWnd, TEXT("window ptr"), pWnd);
pWnd->m_hWnd = hWnd;
lResult = pWnd->WndProc(msg);
}
//ウィンドウのポインタがあったら
if(pWnd)
{
switch(uMsg)
{
case WM_CLOSE:
lResult = pWnd->WndProc(msg);
if(msg.bHandled)return lResult;
::DestroyWindow(hWnd);
return lResult;
case WM_NCDESTROY:
lResult = pWnd->WndProc(msg);
::RemoveProp(hWnd, TEXT("window ptr"));
pWnd->Destruct();
}
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
explicit CWnd(bool bExit = false) : m_hWnd(NULL), m_hInst(::GetModuleHandle(NULL)), m_bExit(bExit){ }
~CWnd(){ if(m_bExit)::PostQuitMessage(0); }
ATOM Regist()
{
WNDCLASSEX wc = {sizeof(wc)};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = &CWnd::StaticProc;
wc.hInstance = m_hInst;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
wc.lpszClassName = TEXT("test c++cli win32");
return ::RegisterClassEx(&wc);
}
HWND Create(int x, int y, int w, int h, HWND hWndParent)
{
return ::CreateWindowEx(WS_EX_CLIENTEDGE,
TEXT("test c++cli win32"),
TEXT("hello win32"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, w, h, hWndParent, NULL, m_hInst, this);
}
HWND Create(int x, int y, int w, int h, System::Windows::Forms::Form^ form)
{ return this->Create(x, y, w, h, static_cast<HWND>(form->Handle.ToPointer())); }
void Destruct(){ delete this; }
protected:
//こっちに転送する
virtual LRESULT WndProc(CMessage& msg){ return FALSE; }
HWND m_hWnd;
HINSTANCE m_hInst;
bool m_bExit;//ココがtrueの場合、閉じたら全てを終了させる
};
//こんな感じで呼び出す
public:Form1(void)
{
InitializeComponent();
//
//TODO: ここにコンストラクタ コードを追加します
//
CWnd* pWnd = new CWnd();
pWnd->Regist();
pWnd->Create(0, 0, this->Width, this->Height, this);
}
お礼
こんばんは。ありがとうございます! ああ、質問が止まりません SetProp/GetProp SetWindowLongPtr/GetWindowLongPtr のいずれかで行う場合は、どちらがより優れていますか? -------------- >ハッシュテーブルの様なデータ構造 というのは、これもやはりあらかじめプロシージャとかなにから全部別途用意しておいて、そっちに飛ばす その際、キャストして、か 評価して、か の違いになるという事でしょうか? -------------- なるほど LPCREATESTRUCTの部分も良く分からなかったのですが そっちにthisがあって、そういう仕掛けになっていたのですね。 納得です。 と、ここで >CREATESTRUCT型のlpCreateParamsメンバ変数に、CreateWindowExの一番最後のパラメータに渡した数値が~ このCREATESTRUCTを使って出来るのかな・・?? という疑問は湧いたのですが、ウインドウの表示非表示切り替えを行いたいのですが、可能なのでしょうか?また、可能だとしてもどのように書けばいいのかピンとこないので、実例を教えていただく事は出来ますでしょうか? http://oshiete1.goo.ne.jp/qa4666555.html