我决定使用这样的基类创建和使用Windows:
class Window
{
private:
static LRESULT WINAPI WindowProc(HWND _hWnd, UINT _uMsg, WPARAM _wParam, LPARAM _lParam);
protected:
virtual LRESULT onMessageNameGoesHere(/*parameters*/)
{
// Default handling
};
public:
// Other functions
};
所以所有窗口都是从这个类继承的。这是WindowProc
。
LRESULT WINAPI Window::WindowProc(HWND _hWnd, UINT _uMsg, WPARAM _wParam, LPARAM _lParam)
{
Window *window = (Window*)GetWindowLongPtr(_hWnd, GWLP_USERDATA);
switch (_uMsg)
{
case WM_SOMEMESSAGE:
return window->onMessageNameGoesHere();
case WM_NCCREATE:
SetWindowLongPtr(_hWnd, GWLP_USERDATA, LONG(LPCREATESTRUCT(_lParam)->lpCreateParams));
return true;
case WM_GETMINMAXINFO:
return window->onGetMinMaxInfo((LPMINMAXINFO)_lParam);
default:
return DefWindowProc(_hWnd, _uMsg, _wParam, _lParam);
}
}
WM_NCCREATE
存储指向与GWLP_USERDATA
中窗口关联的类的指针。问题是在WM_GETMINMAXINFO
之前收到WM_NCCREATE
,导致崩溃。 (是的,我知道我需要一些代码来避免这种情况)
那么有没有办法在没有WM_GETMINMAXINFO
的情况下设置最小和最大窗口大小,或者可能在WM_NCCREATE
之前发送该消息?
随意询问更多细节或进行更多解释。
答案 0 :(得分:1)
我相信答案是“不”。这是Windows OOP模型阻抗与C ++阻抗不匹配的众多地方之一。
我能想到的唯一解决方案是使用RAII来保存/恢复线程本地存储中的上下文指针(确保保存已经存在的内容以避免重入计数)并在消息处理程序中立即检索它叫做。在Windows XP上,您可以尝试__declspec(thread)
或通过TlsAlloc
/ TlsSetValue
明确执行此操作;在Windows Vista或更高版本中,您可能希望使用FlsAlloc
/ FlsSetValue
,但我不确定光纤是否会弄乱这里的内容......