Mon application crée une fenêtre dans le but de gérer le message Windows WM_DEVICECHANGE
. WndProc
est appelée plusieurs fois, jusqu'à ce que mon application appelle une fonction pour interroger les événements clavier, mais pour une raison quelconque, elle n'est pas appelée lorsque je supprime ou insère mon périphérique USB.Les messages WM_DEVICECHANGE ne sont pas envoyés à WndProc - C++
Ceci est le GUID de mon périphérique USB. Je suis sûr qu'il est correct:
static const GUID _guidForCP210xDevices = {
0xA2A39220, 0x39F4, 0x4B88, 0xAE, 0xCB, 0x3D, 0x86, 0xA3, 0x5D, 0xC7, 0x48
};
Voici comment ma fenêtre est créée:
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());
}
Voici comment je me inscrire pour la notification de l'appareil:
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;
Ma fonction WndProc
ressemble ce:
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);
}
Est-ce que quelqu'un sait ce que je fais mal? Merci.
Vous dites que le WndProc fonctionne 'jusqu'à ce que ma fonction d'interrogation des événements clavier soit appelée'. Cela implique que vous empêchez la pompe de messages de traiter d'autres messages - les notifications de votre appareil incluses. Il est assez clair que vous avez excisé du code ici pour plus de clarté, donc il est difficile de dire si c'est le vrai problème. – Jon
Essayez-vous toujours d'exécuter WndProc dans un thread de travail? –
@Jon: Mes excuses, il était censé dire, "... jusqu'à ce que mon application appelle une fonction à interroger pour les événements de clavier." La faute de frappe a été corrigée. En ce qui concerne la pompe de message, qu'est-ce que c'est? Est-ce qu'il fonctionne/appelle 'WndProc' de façon asynchrone? –