USB设备热插拔处理--基于C++Bulild事件
背景描述:
USB设备的即插即用的属性,使得在实际应用中经常会遇到USB设备在程序运行过程中被移除或插入,应用程序需要该事件进行处理。
基于C++ Builder
1.重载WndProc函数
void __fastcall TForm1::WndProc(TMessage &Message)
{
if(Message.Msg == WM_DEVICECHANGE) //帮助里面有这个消息的详细说明
{
if(Message.WParam == DBT_DEVICEARRIVAL)
{
Memo1->Lines->Add("发现USB设备插入!");
}
else if(Message.WParam == DBT_DEVICEREMOVECOMPLETE)
{
Memo1->Lines->Add("USB设备被拔出!");
}
else
{
Memo1->Lines->Add("WM_DEVICECHANGE");
}
}
TForm::WndProc(Message);
}
2.在FormCreat中(或其他合适的地方添加设备注册)
// 这里只是为了得到HID设备的GUID,实际上可以省掉该步骤
typedef __stdcall void(*pGetHidGuid)(GUID* HidGuid);
GUID HidGuid;
pGetHidGuid HidD_GetHidGuid;
HINSTANCE h;
if ((h = LoadLibrary("hid.dll"))==NULL)
{
return;
}
HidD_GetHidGuid=(pGetHidGuid)GetProcAddress(h,"HidD_GetHidGuid");
if(HidD_GetHidGuid==NULL)
{
return;
}
HidD_GetHidGuid(&HidGuid);
// 这里才是注册USB热插拔消息
DEV_BROADCAST_DEVICEINTERFACE DevInt;
memset(&DevInt,0,sizeof(DEV_BROADCAST_DEVICEINTERFACE));
DevInt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
DevInt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
DevInt.dbcc_classguid = HidGuid;
RegisterDeviceNotification(Handle,&DevInt,DEVICE_NOTIFY_WINDOW_HANDLE);
注意事项:
1,一定要在重载的WndProc结束的时候调用基类的WndProc函数继续处理,否则将影响其他功能;
2.HidD_GetHidGuid需要调用动态链接库hid.dll(系统自带了)来完成;
3.Handle从基类继承来,这里无需关心;
4.需要引用系统定义的头文件dbt.h;
5.不同的设备有不同的GUID,所有的HID设备的GUID相同;
6.这里用HID来做例子,其他设备可以直接指定GUID(如果不指定GUID,则为全部USB设备);
基于VC6.0
1.在框体代码找到中加入BEGIN_MESSAGE_MAP/END_MESSAGE_MAP,并加入一行
BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
ON_MESSAGE(WM_DEVICECHANGE, OnDeviceChange)
END_MESSAGE_MAP()
说明:
WM_DEVICECHANGE是Windows定义的设备改变事件,定义在DBT.h中,其值为0x219
OnDeviceChange是用户定义的回调函数.
2.添加回调函数
BOOL CMainDlg::OnDeviceChange(UINT nEventType, DWORD dwData)
{
ShowInfo("Device Changed"); //显示函数(用户定已定义的,调试用)
return TRUE;
}
至此,如果有设备插入及移除已经可以通知到窗体了,但只会收到DBT_DEVNODES_CHANGED事件
(通过nEventType == 0x0007),无法得到详细信息;
3.注册设备
在stdafx.h的第1行加入
#define WINVER 0x0500
注意:一定要加在前边,否则编译会出错
在窗体文件初始化函数OnInitDialog(或其他适当的函数中也行)中添加:
GUID HidGuid;
DEV_BROADCAST_DEVICEINTERFACE DevBroadcastDeviceInterface;
HidD_GetHidGuid(&HidGuid); //获取HID设备的接口类GUDI
DevBroadcastDeviceInterface.dbcc_size=sizeof(DevBroadcastDeviceInterface);
DevBroadcastDeviceInterface.dbcc_devicetype=DBT_DEVTYP_DEVICEINTERFACE;
DevBroadcastDeviceInterface.dbcc_classguid=HidGuid;
//注册设备改变时收到通知
RegisterDeviceNotification(m_hWnd,
&DevBroadcastDeviceInterface,
DEVICE_NOTIFY_WINDOW_HANDLE);
4.修改OnDeviceChange函数
BOOL CAaaDlg::OnDeviceChange(UINT nEventType, DWORD dwData)
{
if(nEventType == DBT_DEVICEARRIVAL)
{
ShowInfo("设备已插入");
}
else if(nEventType == DBT_DEVICEREMOVECOMPLETE)
{
ShowInfo("设备已移除");
}
return TRUE;
}
5.此时系统可以正常捕获到详细的信息DBT_DEVICEARRIVAL/DBT_DEVICEREMOVECOMPLETE等;
继续修改OnDeviceChange函数,以添加期望功能;
注意事项:
m_hWnd(消息接收窗口的句柄)从基类继承;