2010-12-01 2 views
1

Мое приложение создает окно для обработки сообщения 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); 
} 

Кто-нибудь знает, что я делаю неправильно? Благодарю.

+0

Вы говорите, что WndProc работает, пока моя функция для опроса для событий клавиатуры не называется. Это означает, что вы предотвращаете обработку сообщений от любых дальнейших сообщений - включая уведомления о вашем устройстве. Довольно ясно, что вы вырезали код для ясности, поэтому трудно сказать, действительно ли это проблема. – Jon 2010-12-01 17:21:16

ответ

4

Вам не хватает сообщений для извлечения уведомлений из очереди и отправки их на ваш WndProc. Насос сообщения эффективно представляет собой цикл, который проверяет сообщения и вызывает соответствующий WndProc синхронно. MSDN содержит некоторую хорошую информацию о них. Я не знаю, каков контекст вашего кода, поэтому я не уверен, что вам просто нужно вставить насос после RegisterForNotification или если требуется большее архитектурное изменение.