今天看msdn的时候发现之前自己封装的Window类写的完全是错误的。封装window类的时候要建立自己的消息处理函数,但是如果是类成员函数的话,一定要是静态类成员函数才行。所以之前我都把消息处理函数里需要调用的函数都写成静态成员函数...
先来看看CreateWindowEx函数:
HWND WINAPI CreateWindowEx( _In_ DWORD dwExStyle, _In_opt_ LPCTSTR lpClassName, _In_opt_ LPCTSTR lpWindowName, _In_ DWORD dwStyle, _In_ int x, _In_ int y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam );
最后一个参数LPVOID lpParam用来传递参数。并可以在响应WM_NCCREATE消息的时候,通过lParam参数获取该参数,代码如下:
if (uMsg == WM_NCCREATE) { CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam; T* pThis = (T*)pCreate->lpCreateParams; SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
pThis->mhwnd = hwnd; }
其中SetWindowLongPtr函数用来保存该参数,并可通过GetWindowLongPtr函数再次获取该参数:
T* pThis = (T*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
有了这些,就可以不用把处理消息的函数写成静态函数了,方法如下(摘抄自MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/ff381400(v=vs.85).aspx )
template <class DERIVED_TYPE> class BaseWindow { public: static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { DERIVED_TYPE *pThis = NULL; if (uMsg == WM_NCCREATE) { CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam; pThis = (DERIVED_TYPE*)pCreate->lpCreateParams; SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis); pThis->m_hwnd = hwnd; } else { pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA); } if (pThis) { return pThis->HandleMessage(uMsg, wParam, lParam); } else { return DefWindowProc(hwnd, uMsg, wParam, lParam); } } BaseWindow() : m_hwnd(NULL) { } BOOL Create( PCWSTR lpWindowName, DWORD dwStyle, DWORD dwExStyle = 0, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int nWidth = CW_USEDEFAULT, int nHeight = CW_USEDEFAULT, HWND hWndParent = 0, HMENU hMenu = 0 ) { WNDCLASS wc = {0}; wc.lpfnWndProc = DERIVED_TYPE::WindowProc; wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = ClassName(); RegisterClass(&wc); m_hwnd = CreateWindowEx( dwExStyle, ClassName(), lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, GetModuleHandle(NULL), this ); return (m_hwnd ? TRUE : FALSE); } HWND Window() const { return m_hwnd; } protected: virtual PCWSTR ClassName() const = 0; virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0; HWND m_hwnd; };
具体就是窗口创建时传递this指针。处理消息时调用
this->HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) 方法