Мое приложение создает окно для обработки сообщения Windows WM_DEVICECHANGE
. WndProc
вызывает несколько раз, пока мое приложение не вызовет функцию для опроса для событий клавиатуры, но по какой-либо причине она не вызывается при удалении или вставке моего устройства USB.Сообщения WM_DEVICECHANGE не отправлены в WndProc - C++
Это GUID для моего устройства USB. Я уверен, что это правильно:
static const GUID _guidForCP210xDevices = {
0xA2A39220, 0x39F4, 0x4B88, 0xAE, 0xCB, 0x3D, 0x86, 0xA3, 0x5D, 0xC7, 0x48
};
Это как создается мое окно:
m_hInstance = ::GetModuleHandle(NULL);
if (m_hInstance == NULL)
{
TRACE(_T("CNotifyWindow::CNotifyWindow : Failed to retrieve the module handle.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
THROW(::GetLastError());
}
m_wcx.cbSize = sizeof(WNDCLASSEX); // size of structure
m_wcx.style = CS_HREDRAW | CS_VREDRAW; // initially minimized
m_wcx.lpfnWndProc = &WndProc; // points to window procedure
m_wcx.cbClsExtra = 0; // no extra class memory
m_wcx.cbWndExtra = 0; // no extra window memory
m_wcx.hInstance = m_hInstance; // handle to instance
m_wcx.hIcon = ::LoadIcon(NULL, IDI_APPLICATION); // default app icon
m_wcx.hCursor = ::LoadCursor(NULL, IDC_ARROW); // standard arrow cursor
m_wcx.hbrBackground = NULL; // no background to paint
m_wcx.lpszMenuName = NULL; // no menu resource
m_wcx.lpszClassName = _pwcWindowClass; // name of window class
m_wcx.hIconSm = NULL; // search system resources for sm icon
m_atom = ::RegisterClassEx(&m_wcx);
if (m_atom == 0)
{
TRACE(_T("CNotifyWindow::CNotifyWindow : Failed to register window class.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
THROW(::GetLastError());
}
m_hWnd = ::CreateWindow(
_pwcWindowClass,
_pwcWindowName,
WS_ICONIC,
0,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
m_hInstance,
NULL
);
if (m_hWnd == NULL)
{
TRACE(_T("CNotifyWindow::CNotifyWindow : Failed to create window.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
THROW(::GetLastError());
}
::ShowWindow(m_hWnd, SW_HIDE); // function does not fail
if (RegisterForNotification() != ERROR_SUCCESS)
{
TRACE(_T("CNotifyWindow::CNotifyWindow : Failed to register for device notification.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
THROW(::GetLastError());
}
Это, как зарегистрироваться для уведомления устройства:
static DEV_BROADCAST_DEVICEINTERFACE dbt = {0};
ASSERT(m_hWnd != NULL);
// Populate DEV_BROADCAST_DEVICEINTERFACE structure.
dbt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
dbt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
dbt.dbcc_classguid = _guidForCP210xDevices;
// Register for HID devic notifications
m_hNotify = RegisterDeviceNotification(m_hWnd, &dbt, DEVICE_NOTIFY_WINDOW_HANDLE);
if (m_hNotify == NULL)
{
TRACE(_T("CNotifyWindow::RegisterForNotification : Failed to register for device notification.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
return ::GetLastError();
}
return ERROR_SUCCESS;
Моя WndProc
функция выглядит это:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DEV_BROADCAST_HDR * pHeader = reinterpret_cast<DEV_BROADCAST_HDR *>(lParam);
switch (uMsg)
{
case WM_DEVICECHANGE:
if (pHeader != NULL)
{
if (pHeader->dbch_devicetype == DBT_DEVTYP_PORT)
{
OnDeviceChange(wParam);
}
}
break;
default:
// Do nothing.
break;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Кто-нибудь знает, что я делаю неправильно? Благодарю.
Вы говорите, что WndProc работает, пока моя функция для опроса для событий клавиатуры не называется. Это означает, что вы предотвращаете обработку сообщений от любых дальнейших сообщений - включая уведомления о вашем устройстве. Довольно ясно, что вы вырезали код для ясности, поэтому трудно сказать, действительно ли это проблема. – Jon 2010-12-01 17:21:16