WM_DESTROY没有在包装的WndProc中调用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WM_DESTROY没有在包装的WndProc中调用相关的知识,希望对你有一定的参考价值。
我已经采用了你在那里找到的典型解决方案,以便使用WNDPROC
作为对象方法,但看起来WM_DESTROY
消息不会发送到对象窗口自己的WNDPROC
,并且程序在关闭窗口后不会退出。
我的窗口类看起来像这样(删除了不相关的代码):
class MyWindow : MyApp
{
public:
MyWindow();
void Create(void);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
private:
HWND _hWnd;
};
void MyWindow::Create()
{
// Here I register my class and call CreateWindowEx
// Everything works fine so far
// Part of the code where I assign the static WNDPROC
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MyApp::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = this->Instance;
wcex.hIcon = LoadIcon(this->Instance, MAKEINTRESOURCE(32512));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "MyWindowClass";
wcex.hIconSm = LoadIcon(this->Instance, MAKEINTRESOURCE(32512));
RegisterClassExW(&wcex);
this->_hWnd = CreateWindowExW(
WS_EX_TOOLWINDOW | WS_EX_TOOLWINDOW,
wcex.lpszClassName,
"Window Title",
WS_POPUP,
10, 10,
600, 400,
nullptr,
nullptr,
this->Instance,
nullptr
);
ShowWindow(this->_hWnd, SW_SHOW);
UpdateWindow(this->_hWnd);
}
LRESULT CALLBACK MyWindow::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
// If I place a MessageBox here, it shows up
}
break;
case WM_DESTROY:
// It never gets to this point
// Decrease windows count
this->WindowsCount--;
PostQuitMessage(0);
break;
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
现在是一个包含静态WNDPROC的类,它在创建时分配
class MyApp
{
public:
static HINSTANCE Instance;
static int WindowsCount;
MyApp();
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
};
和实施
LRESULT CALLBACK MyApp::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Window object
MyWindow* myWindow = NULL;
if (msg == WM_CREATE) {
myWindow = reinterpret_cast<MyWindow *>(((LPCREATESTRUCT)lParam)->lpCreateParams);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)myWindow);
}
else {
myWindow = reinterpret_cast<MyWindow *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
}
// If window not identified, identify now
if (myWindow) {
return myWindow->WndProc(hWnd, msg, wParam, lParam);
}
// Call window object's processor
return DefWindowProc(hWnd, msg, wParam, lParam);
}
WM_CLOSE
消息也没有捕获。我真的不明白为什么不传递这些消息
答案
你正在将lpParam
的CreateWindowEx()
参数设置为nullptr
,所以myWindow
在nullptr
中始终是MyApp::WndProc()
,因此MyWindow::WndProc()
永远不会被调用。你需要通过this
而不是nullptr
。
在调用RegisterClassExW()
/ CreateWindowEx()
之前,你也没有进行任何错误检查以确保ShowWindow()
和UpdateWindow()
成功。
另外,考虑使用SetWindowSubclass()
而不是(Get|Set)WindowLongPtr(GWLP_USERDATA)
。请参阅MSDN上的Subclassing Controls和Raymond Chen关于Safer Subclassing的博客文章。
以上是关于WM_DESTROY没有在包装的WndProc中调用的主要内容,如果未能解决你的问题,请参考以下文章