之前看mfc的原理是做類指針對窗口句柄的映射表;
實現了幾個版本,總覺得查找映射表是件很浪費不優雅的事情,尤其在窗口很多的時候,比如大量使用了子類化的win32控件這種常出現的情況;
於是,利用窗口的USERDATA,有如下版本的實現,大概如下:
class XWindow
{
protected:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
XWindow* pWindow;
if (WM_NCCREATE == uMsg)
{
MDICREATESTRUCT* pMDIC = (MDICREATESTRUCT*)((LPCREATESTRUCT)lParam)->lpCreateParams;
pWindow = (XWindow*)(pMDIC->lParam);
::SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
}
else
{
pWindow=(XWindow*)::GetWindowLong(hWnd, GWL_USERDATA);
}
if (NULL != pWindow)
{
return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
}
else
{
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
virtual LRESULT WndProcSelf(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//this is self wndproc
}
virtual HWND CreateEx(DWORD dwExStyle,
LPCTSTR lpszClass,
LPCTSTR lpszName,
DWORD dwStyle,
int x, int y,
int nWidth, int nHeight,
HWND hParent,
HMENU hMenu,
HINSTANCE hInst)
{
MDICREATESTRUCT mdic;
memset(& mdic, 0, sizeof(mdic));
mdic.lParam = (LPARAM) this;
return CreateWindowEx(dwExStyle,
lpszClass,
lpszName,
dwStyle,
x, y,
nWidth, nHeight,
hParent,
hMenu,
hInst,
& mdic);
}
private:
HWND m_hWnd;
};
這樣,想做消息映射就so easy了,可以在靜態窗口過程中加映射或者在成員窗口過程中加映射;