方法一:
启动定时器,定时轮询注册表,这种方法容易死机。
方法二:
注册窗口,添加Windows消息 ON_WM_DEVICECHANGE()映射。
步骤:
一: 要想添加消息映射,需改变三个地方:
1、 窗口头文件声明消息处理函数
afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData)
2、 源文件添加消息处理函数
BOOL CDownLoadDlg::OnDeviceChange(UINT nEventType,DWORD dwData)
{
// TODO: 在此添加额外的初始化代码
}
3、 源文件添加消息
BEGIN_MESSAGE_MAP(CDownLoadDlg, CDialog)
‘’‘’‘’‘’‘’
ON_WM_DEVICECHANGE()//USB消息
END_MESSAGE_MAP()
二: 消息处理函数的OnDeviceChange
MSDN说明:
The framework calls this member function to notify an application or device driver of a change to the hardware configuration of a device or the computer.
afx_msg BOOL OnDeviceChange( UINT nEventType,
DWORD_PTR dwData
);
Parameters
-
nEventType
-
An event type. See the Remarks section for a description of the available values
-
dwData
-
The address of a structure that contains event-specific data. Its meaning depends on the given event.
For devices that offer software-controllable features, such as ejection and locking, the operating system typically sends a DBT_DEVICEREMOVEPENDING message to let applications and device drivers end their use of the device gracefully.
If the operating system forcefully removes of a device, it may not send a DBT_DEVICEQUERYREMOVE message before doing so.
The nEvent parameter can be one of these values:
-
DBT_DEVICEARRIVAL A device has been inserted and is now available.
-
DBT_DEVICEQUERYREMOVE Permission to remove a device is requested. Any application can deny this request and cancel the removal.
-
DBT_DEVICEQUERYREMOVEFAILED Request to remove a device has been canceled.
-
DBT_DEVICEREMOVEPENDING Device is about to be removed. Cannot be denied.
-
DBT_DEVICEREMOVECOMPLETE Device has been removed.
-
DBT_DEVICETYPESPECIFIC Device-specific event.
-
DBT_CONFIGCHANGED Current configuration has changed.
-
DBT_DEVNODES_CHANGED Device node has changed.
例子:
BOOL CDownLoadDlg::OnDeviceChange(UINT nEventType,DWORD dwData)
{
// DEV_BROADCAST_DEVICEINTERFACE* dbd = (DEV_BROADCAST_DEVICEINTERFACE*) dwData;//这里进行信息匹配,比如guid等
PDEV_BROADCAST_HDRdbd =(PDEV_BROADCAST_HDR)dwData;
//针对各个事件进行处理.
m_StrResult.Empty();
switch (nEventType)
{
case DBT_DEVICEREMOVECOMPLETE:
if(dbd->dbch_devicetype==DBT_DEVTYP_DEVICEINTERFACE)
{
DEV_BROADCAST_DEVICEINTERFACE *get_dbd;
get_dbd=(DEV_BROADCAST_DEVICEINTERFACE*) dwData;
//名字对比
unsigned shortlength,VID,PID,i;
unsigned char numb[8];
CString get_hid_name;
get_hid_name.Format(_T("%s"),get_dbd->dbcc_name);
length=get_hid_name.GetLength();
if(length<10)
{
return false;
}
for(i=0;i<length-3;i++)
{
if(('H'==get_hid_name.GetAt(i)) && ('I'==get_hid_name.GetAt(i+1)) && ('D'==get_hid_name.GetAt(i+2)))
break;
}
if(i==(length-3))
{
return false;
}
length=i;
for(i=0;i<4;i++)
{
if((get_hid_name.GetAt(i+8+length)<=0x39) && (get_hid_name.GetAt(i+8+length)>=0x30))
{
numb[i]=get_hid_name.GetAt(i+8+length);
numb[i]=numb[i]-0x30;
}
if((get_hid_name.GetAt(i+8+length)<=0x5A) && (get_hid_name.GetAt(i+8+length)>=0x41))
{
numb[i]=get_hid_name.GetAt(i+8+length);
numb[i]=numb[i]-0x37;
}
if((get_hid_name.GetAt(i+8+length)<=0x7A) && (get_hid_name.GetAt(i+8+length)>=0x61))
{
numb[i]=get_hid_name.GetAt(i+8+length);
numb[i]=numb[i]-0x57;
}
if((get_hid_name.GetAt(i+17+length)<=0x39) && (get_hid_name.GetAt(i+17+length)>=0x30))
{
numb[i+4]=get_hid_name.GetAt(i+17+length);
numb[i+4]=numb[i+4]-0x30;
}
if((get_hid_name.GetAt(i+17+length)<=0x5A) && (get_hid_name.GetAt(i+17+length)>=0x41))
{
numb[i+4]=get_hid_name.GetAt(i+17+length);
numb[i+4]=numb[i+4]-0x37;
}
if((get_hid_name.GetAt(i+17)<=0x7A+length) && (get_hid_name.GetAt(i+17+length)>=0x61))
{
numb[i+4]=get_hid_name.GetAt(i+17+length);
numb[i+4]=numb[i+4]-0x57;
}
}
VID=numb[0];
VID=VID<<4;
VID=VID & 0x00F0;
VID=VID |(numb[1] & 0x000F);
VID=VID<<4;
VID=VID & 0x0FF0;
VID=VID |(numb[2] & 0x000F);
VID=VID<<4;
VID=VID & 0xFFF0;
VID=VID |(numb[3] & 0x000F);
PID=numb[4];
PID=PID<<4;
PID=PID & 0x00F0;
PID=PID |(numb[5] & 0x000F);
PID=PID<<4;
PID=PID & 0x0FF0;
PID=PID |(numb[6] & 0x000F);
PID=PID<<4;
PID=PID & 0xFFF0;
PID=PID |(numb[7] & 0x000F);
if((VID==USB_VID) && (PID==USB_PID))
{
CloseUSB();
EditWrite(_T("下载器已移除\r\n"),_T("未连接"));
}
}
else
{
return false;
}
break;
case DBT_DEVICEARRIVAL:
if(hidHandle == INVALID_HANDLE_VALUE)
{
HIDFindFunc();
}
break;
default:
return false;
break;
}
return TRUE;
}
二、设备注册
如果想获得正确的 nEventType 值,必须先在窗口初始化函数OnInitDialog()里面进行注册,否则值都是7,切要在函数最后(DoModal()函数之后)调用。注册函数用RegisterDeviceNotification()。
MSDN说明:
Registers the device or type of device for which a window will receive notifications.
Syntax
Parameters
-
hRecipient [in]
-
A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter. The same window handle can be used in multiple calls to RegisterDeviceNotification.
Services can specify either a window handle or service status handle.
NotificationFilter [in]
-
A pointer to a block of data that specifies the type of device for which notifications should be sent. This block always begins with the DEV_BROADCAST_HDR structure. The data following this header is dependent on the value of the dbch_devicetype member, which can be DBT_DEVTYP_DEVICEINTERFACE or DBT_DEVTYP_HANDLE. For more information, see Remarks.
Flags [in]
-
This parameter can be one of the following values.
Value Meaning -
DEVICE_NOTIFY_WINDOW_HANDLE
0x00000000
The hRecipient parameter is a
window handle.-
DEVICE_NOTIFY_SERVICE_HANDLE
0x00000001
The hRecipient parameter is a service
status handle.In addition, you can specify the following value.
Return value
If the function succeeds, the return value is a device notification handle.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
Remarks
Applications send event notifications using the BroadcastSystemMessage function. Any application with a top-level window can receive basic notifications by processing the WM_DEVICECHANGE message. Applications can use theRegisterDeviceNotification function to register to receive device notifications.
Services can use the RegisterDeviceNotification function to register to receive device notifications. If a service specifies a window handle in the hRecipient parameter, the notifications are sent to the window procedure. IfhRecipient is a service status handle, SERVICE_CONTROL_DEVICEEVENT notifications are sent to the service control handler. For more information about the service control handler, see HandlerEx.
Be sure to handle Plug and Play device events as quickly as possible. Otherwise, the system may become unresponsive. If your event handler is to perform an operation that may block execution (such as I/O), it is best to start another thread to perform the operation asynchronously.
Device notification handles returned by RegisterDeviceNotification must be closed by calling the UnregisterDeviceNotification function when they are no longer needed.
The DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE events are automatically broadcast to all top-level windows for port devices. Therefore, it is not necessary to call RegisterDeviceNotification for ports, and the function fails if the dbch_devicetype member is DBT_DEVTYP_PORT. Volume notifications are also broadcast to top-level windows, so the function fails if dbch_devicetype is DBT_DEVTYP_VOLUME. OEM-defined devices are not used directly by the system, so the function fails if dbch_devicetype is DBT_DEVTYP_OEM.
例子: