关于HID设备与WM_DEVICECHANGE
各位,问一个问题,当HID设备如USB鼠标或键盘插上或拔除时,系统向各窗口发送WM_DEVICECHANGE消息所带的wParam,lParam等相关信息,我在程序中试了一下,插入USB鼠标,系统收到4条WM_DEVICECHANGE消息,wParam都显示为0X07,VC中有#define DBT_DEVNODES_CHANGED 0x0007 而拔除USB鼠标系统收到2条WM_DEVICECHANGE消息,wParam都显示为0X07 而插入或拔除U盘时系统除了收到几条WM_DEVICECHANGE消息,wParam都显示为0X07外, 还有分别有wParam显示为0X8000或0x8004 ,VC中#define BT_DEVICEARRIVAL 0x8000,#define DBT_DEVICEREMOVECOMPLETE 0x8004,那请问HID设备如USB鼠标或键盘插上或拔除时WM_DEVICECHANGE消息的wParam有什么规律,有没有熟悉的,指导指导
另我在程式的消息循环中,处理WM_DEVICECHANGE消息,即窗口每收到一个WM_DEVICECHANGE消息,即使用一个消息框把该消息的wParam值显示出来,我的程序运行后,当HID设备如USB鼠标或键盘插上或拔除时,或插入或拔除U盘时收到的消息如上所述收到那些消息,但是我让我的程序一直开着,不插拔任何USB鼠标或键盘或U盘(不插拔任何设备,间隔大概7至8分钟左右,我发现程序中每次还是弹出3个消息框,显示wParam值为0x0007,我看到设备管理器窗口也闪一下,但我试着找是否有相关时而断开,时而连上,而导致窗口收到WM_DEVICECHANGE,基本没发现什么硬件有问题啊,有没有谁知道是咋会事?
[解决办法]
直接响应DBT_DEVTYP_DEVICEINTERFACE就可以了,其它可以不用处理
看这个例子,基本上可以直接用
Detecting Hardware Insertion and/or Removal
http://www.codeproject.com/KB/system/HwDetect.aspx
[解决办法]
关键的就是两个函数处理
- C/C++ code
LRESULT CHWDetectDlg::OnMyDeviceChange(WPARAM wParam, LPARAM lParam){ if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) { PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; PDEV_BROADCAST_DEVICEINTERFACE pDevInf; PDEV_BROADCAST_HANDLE pDevHnd; PDEV_BROADCAST_OEM pDevOem; PDEV_BROADCAST_PORT pDevPort; PDEV_BROADCAST_VOLUME pDevVolume; switch( pHdr->dbch_devicetype ) { case DBT_DEVTYP_DEVICEINTERFACE: pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; UpdateDevice(pDevInf, wParam); break; case DBT_DEVTYP_HANDLE: pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr; break; case DBT_DEVTYP_OEM: pDevOem = (PDEV_BROADCAST_OEM)pHdr; break; case DBT_DEVTYP_PORT: pDevPort = (PDEV_BROADCAST_PORT)pHdr; break; case DBT_DEVTYP_VOLUME: pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr; break; } } return 0;}
[解决办法]
看起来是硬件连接不好,你先把各种USB设备都拔除,看看还会不会收到消息。
[解决办法]
/*
* Message = WM_DEVICECHANGE
* wParam = DBT_DEVNODES_CHANGED
* lParam = 0
*
* send when configmg finished a process tree batch. Some devnodes
* may have been added or removed. This is used by ring3 people which
* need to be refreshed whenever any devnode changed occur (like
* device manager). People specific to certain devices should use
* DBT_DEVICE* instead.
*/
#define DBT_DEVNODES_CHANGED 0x0007
是用来刷新节点的,一般不处理