1:监控打开后,连接USB设备:
2:USB设备连接状态时,打开监控,拔除后重新连接:
3:USB插拔多次的结果:
非首次连接新设备:
1:移除USB时,首先收到两次DBT_DEVNODES_CHANGED。然后会收到一次 DBT_DEVICEREMOVECOMPLETE。
2:插入USB时,首先会收到三次DBT_DEVNODES_CHANGED,然后会收到一次 DBT_DEVICEARRIVAL,之后还会收到一次DBT_DEVNODES_CHANGED。
首次连接新设备:
1:插入USB时,
首先收到四次DBT_DEVNODES_CHANGED,
然后收到一次DBT_DEVICEARRIVAL,
然后收到两次DBT_DEVNODES_CHANGED,
然后收到一次DBT_DEVICEREMOVECOMPLETE,
然后收到一次DBT_DEVNODES_CHANGED,
然后收到一次DBT_DEVICEARRIVAL,
然后收到一次DBT_DEVNODES_CHANGED。
2:移除USB时:
首先收到两次DBT_DEVNODES_CHANGED,
然后收到一次DBT_DEVICEREMOVECOMPLETE。
1:对于新设备(首次连接)或非首次连接设备,统一起见,我们做如下处理:
处理OnDeviceChange消息中,根据接收到的DBT_DEVNODES_CHANGED的次数(3,5,6,7及以上)来判断是否识别成功,其中nMessageNum为接收DBT_DEVNODES_CHANGED的次数。
2:对于消息DBT_DEVICEQUERYREMOVE的获取,参考http://blog.csdn.net/Sephoenix/article/details/5442064的方法。
WM_DEVICECHANGE 里默认是只注册了 DBT_DEVICEREMOVECOMPLETE 和 DBT_DEVICEARRIVAL 消息,所以只能接收到这两个,如果要使用其他的消息,必需手动注册一下才可以。
void CNIBPTestSoftDlg::OnDeviceChange(UINT nEventType, DWORD dwData)
{
switch(nEventType)
{
case DBT_DEVICEREMOVECOMPLETE: //设备移除
{
_cprintf("----DBT_DEVICEREMOVECOMPLETE--检测到设备移除完成\n");
PDEV_BROADCAST_HDR pdb;
pdb = (PDEV_BROADCAST_HDR)dwData;
if(pdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE pDevInf;
pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pdb;
TRACE("%s\n", pDevInf->dbcc_name);
CString strPath = pDevInf->dbcc_name;
//将关联此路径的HID模拟仪设备窗口置为可用状态
for(int n=0; nGetHIDDevPath();
strTemp.MakeUpper();
strPath.MakeUpper();
if(strTemp == strPath)
{
int nComNum = m_vecTestWnd.at(n)->m_nComNum;
m_mapSimulateInfo[nComNum].bFlagUse = FALSE; //置为可用状态
m_vecTestWnd.at(n)->OnRemove(); //移除设备信息
break;
}
}
}
break;
}
case DBT_DEVICEARRIVAL://表示有设备插入并可用,
{
_cprintf("----DBT_DEVICEARRIVAL--检测到新设备连接并可用\n");
PDEV_BROADCAST_HDR pdb;
pdb = (PDEV_BROADCAST_HDR)dwData;
if(pdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
if (nMessageNum >= 7 || nMessageNum == 3 || nMessageNum == 5 || nMessageNum == 6)
{
_cprintf("检测完成----执行FreshDeviceChange函数---nMessageNum清零---\n");
Sleep(1000);
nMessageNum = 0;
FreshDeviceChange();
}
}
break;
}
case DBT_DEVNODES_CHANGED:
{
_cprintf("----DBT_DEVNODES_CHANGED---接收第%d次\n", ++nMessageNum);
break;
}
case DBT_DEVICEQUERYREMOVE:
{
_cprintf("----DBT_DEVICEQUERYREMOVE---检测到设备准备移除\n");
break;
}
}
return;
}
参考:http://blog.hehehehehe.cn/a/410.htm
插入u盘时,会发送好几次WM_DEVICECHANGE消息。
要检测设备插入或者移除,最好使用DBT_DEVICEARRIVAL和DBT_DEVNODES_CHANGED来细分判断,当插入USB的时候WM_DEVICECHANGE会发生很多次。
当你USB插入的时候会收到WM_DEVICECHANGE消息,其WPARAM为DBT_DEVICEARRIVAL,另外还会接受到六个DBT_DEVNODES_CHANGED ,此消息表示虚拟设备的插入和删除,第一次接受DBT_DEVICEARRIVAL,表示设备插入成功,后面的DBT_DEVNODES_CHANGED表示文件系统,驱动设备更新完毕.
如果想通过WM_DEVICECHANGE消息来判断,当设备插入,设备拨出,设备准备好,都会发生WM_DEVICECHANGE消息,使用的时候需要判断wParam的值。