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