1
我的应用程序有一个消息窗口,它是从新创建的线程启动的。线程函数创建消息窗口并运行消息泵。我遇到的问题是消息泵永远不会得到WM_CLOSE
消息。我删除了错误处理来简化发布的代码。有谁知道我做错了什么?无法关闭仅消息窗口 - C++
构造:
this->m_hInstance = ::GetModuleHandle(NULL);
this->m_wcx.cbSize = sizeof(WNDCLASSEX); // size of structure
this->m_wcx.style = CS_HREDRAW | CS_VREDRAW; // initially minimized
this->m_wcx.lpfnWndProc = &WndProc; // points to window procedure
this->m_wcx.cbClsExtra = 0; // no extra class memory
this->m_wcx.cbWndExtra = 0; // no extra window memory
this->m_wcx.hInstance = m_hInstance; // handle to instance
this->m_wcx.hIcon = ::LoadIcon(NULL, IDI_APPLICATION); // default app icon
this->m_wcx.hCursor = ::LoadCursor(NULL, IDC_ARROW); // standard arrow cursor
this->m_wcx.hbrBackground = NULL; // no background to paint
this->m_wcx.lpszMenuName = NULL; // no menu resource
this->m_wcx.lpszClassName = s_pwcWindowClass; // name of window class
this->m_wcx.hIconSm = NULL; // search system resources for sm icon
this->m_atom = ::RegisterClassEx(&m_wcx);
this->m_hNotifyWindowThread = ::CreateThread(
NULL, // no security attributes
0, // use default initial stack size
reinterpret_cast<LPTHREAD_START_ROUTINE>(NotifyWindowThreadFn), // function to execute in new thread
NULL, // thread parameters
0, // use default creation settings
NULL // thread ID is not needed
);
析构函数:
::DestroyWindow(this->m_hWnd);
::WaitForSingleObject(this->m_hNotifyWindowThread, NW_DEFAULT_TIMEOUT); // <-- Seems to get stuck here.
::UnregisterClass(s_pwcWindowClass, this->m_hInstance);
线程功能:
s_ptInterface->pobjNotifyWindow->m_hWnd = ::CreateWindow(
s_pwcWindowClass, // window class name
s_pwcWindowName, // window name
WS_ICONIC, // window style is minimized
0, // initial horizontal position
0, // initial vertical position
CW_USEDEFAULT, // window width
0, // window height
NULL, // no parent window
NULL, // no menu
s_ptInterface->pobjNotifyWindow->GetInstanceHandle(), // associated instance
NULL // no additional info for WM_CREATE
);
::ShowWindow(s_ptInterface->pobjNotifyWindow->GetWindowHandle(), SW_HIDE);
::UpdateWindow(s_ptInterface->pobjNotifyWindow->GetWindowHandle();
dbt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
dbt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
dbt.dbcc_classguid = s_guidForCP210xDevices;
m_hNotify = RegisterDeviceNotification(m_hWnd, &dbt, DEVICE_NOTIFY_WINDOW_HANDLE);
while ((blRetVal = ::GetMessage(
&msg, // message structure
NULL, // retrieve messages for all windows on this thread
0, // lowest message value to retrieve
0 // highest message value to retrieve
)) != 0)
{
if (blRetVal == -1)
{
return ::GetLastError();
}
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
窗口过程:
switch (uMsg)
{
case WM_CLOSE:
if (m_hNotify != NULL)
{
::UnregisterDeviceNotification(m_hNotify);
m_hNotify = NULL;
}
::DestroyWindow(hWnd);
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_DEVICECHANGE:
if (pHeader != NULL)
{
if (pHeader->dbch_devicetype == DBT_DEVTYP_PORT)
{
switch (wParam)
{
case DBT_DEVICEREMOVECOMPLETE: // Device is gone
::EnterCriticalSection(&(s_ptInterface->csSerialPort));
s_ptInterface->pobjSerialPort->Close();
::LeaveCriticalSection(&(s_ptInterface->csSerialPort));
break;
case DBT_DEVICEARRIVAL: // System detected device
::EnterCriticalSection(&(s_ptInterface->csSerialPort));
s_ptInterface->pobjSerialPort->Open();
::LeaveCriticalSection(&(s_ptInterface->csSerialPort));
break;
default:
// Do nothing.
break;
}
}
}
break;
default:
// Do nothing.
break;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
如果我理解正确,因为这是一个只有消息的窗口(隐藏给用户)并且从析构函数调用DestroyWindow,所以不需要处理WndProc中的WM_CLOSE消息。这仍然会让PC在析构函数中陷入'WaitForSingleObject'问题。我如何向窗口发送一条WM_DESTROY消息?我以为'DestroyWindow'做到了。 – 2011-04-27 13:36:18
唯一想到的是我使用's_ptInterface-> pobjNotifyWindow->'这样的指针来访问我为此只消息窗口编写的'CNotifyWindow'类的公共成员。你认为我应该让这些共享资源成为静态全局变量,而不是公共类成员?我在过去遇到过很多关键部分的问题。 – 2011-04-27 13:39:43
好的,我明白了。消息使用SendMessage发送。通过在析构函数中用'SendMessage'切换出DestroyWindow来发送'WM_CLOSE'解决了这个问题。感谢您指点我正确的方向! – 2011-04-27 14:45:13