我查看了这个主题的许多教程和post,他们都说我在我的CreateWindowEx()
函数中传递类实例指针( this
),然后在发送WM_NCCREATE
消息时将其存储在窗口过程函数中。 我想这是因为WM_NCCREATE
被认为是第一个消息被发送到窗口过程,因为窗口被创build。
几个问题/笔记:
从debugging我来知道,实际上WM_GETMINMAXINFO
是WM_NCCREATE
(至less在我的机器) 之前的第一个发送的消息。 这是否意味着我应该听取这个消息,而不是WM_NCCREATE
?
根据这篇受欢迎的文章,大家在收到WM_NCCREATE
消息之后调用SetWindowLongPtr()
的原因是因为
如果在调用WM_NCCREATE的时候该值不存在,那么通过一些神秘的Windows行为,我仍然不明白,值永远不会被插入。
我试图做到这一点(即,在CreateWindowEx()
之后调用SetWindowLongPtr()
CreateWindowEx()
)。 事实certificate,这很好。 应用程序运行正常。 下面是我的代码,请告诉我这种方法是否有问题。
void GLWin32::CreateWindow(...) { ... _hwnd = CreateWindowEx(NULL, _wndclassex.lpszClassName, title.c_str(), WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, _hinstance, NULL); SetWindowLongPtr(_hwnd, GWL_USERDATA, reinterpret_cast<LONG_PTR>(this)); ... } //static window procedure for all instances of this class LRESULT CALLBACK GLWin32::_msgRouter(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { LONG l = GetWindowLongPtr(hwnd, GWLP_USERDATA); GLWin32* thisPtr = reinterpret_cast<GLWin32*>(l); if (thisPtr) return thisPtr->_winProc(msg, wparam, lparam); else return DefWindowProc(hwnd, msg, wparam, lparam); } LRESULT GLWin32::_winProc(UINT msg, WPARAM wparam, LPARAM lparam) { switch (msg) { case WM_CLOSE: { PostQuitMessage(0); return 0; } } return DefWindowProc(_hwnd, msg, wparam, lparam); }
为什么不使用我的方法,而不是使用stream行的方法 ?
这种方法的问题在于,如果要在处理任何窗口创建消息(包括作为创建过程的一部分发送的“普通”消息)时使用实例,则无法访问它。
假设你想在处理WM_CREATE (典型场景)时创建一个按钮,并且你想将按钮文本设置为某个实例成员值。 你想要的东西像:
LRESULT GLWin32::_winProc(UINT msg, WPARAM wparam, LPARAM lparam) { switch (msg) { case WM_CREATE: { CreateWindow("BUTTON", this->buttonText, WS_VISIBLE | WS_CHILD, 10, 10, 50, 30, this->hwnd, NULL, this->hInstance, NULL); return 0; } } return DefWindowProc(_hwnd, msg, wparam, lparam); }
问题是,当WM_CREATE被处理时(在CreateWindowEx
返回之前), SetWindowLongPtr
还没有被调用,并且实例指针丢失了,所以_winProc
根本没有被调用。