mfc 实现 设备 热插拔功能

开发windows MFC 应用程序时,经常会操作一些硬件设备,那么如何实现设备的热插拔功能呢,下面给出具体操作步骤:

1,给要实现设备热插拔的窗体/界面 添加  ON_WM_DEVICECHANGE() 消息,如下在 BEGIN_MESSAGE_MAP (...)

与END_MESSAGE_MAP() 之间加入 一行“ ON_WM_DEVICECHANGE() ”

BEGIN_MESSAGE_MAP(CServoTestDlg, CDialog)

	...

	ON_WM_DEVICECHANGE()

	...

END_MESSAGE_MAP()

2,给窗体注册 插拔事件,一般可在 OnInitDialog()函数 中加入 ,代码如下:

BOOL xxx::OnInitDialog()
{
	int i,j;
	CDialog::OnInitDialog();

	...

	//注册插拔事件
	HDEVNOTIFY hDevNotify; 
	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
	ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
	NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	
	for (int i = 0; i<sizeof(GUID_DEVINTERFACE_LIST) / sizeof(GUID); i++)
	{
		NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
		hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
		if (!hDevNotify)
		{
			return FALSE;
		}

	}

	return TRUE;    
}

上面中会用到一些常量 GUID_DEVINTERFACE_LIST ,这里定义了 设备的一些信息,如下:

static const GUID GUID_DEVINTERFACE_LIST[] =
{
	// GUID_DEVINTERFACE_USB_DEVICE
	{ 0xA5DCBF10, 0x6530, 0x11D2,{ 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } },
	// GUID_DEVINTERFACE_HID, 
	{ 0x4D1E55B2, 0xF16F, 0x11CF,{ 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } },
};

上面显示这个窗体关事的设备是USB设备,HID设备。

3,实现 OnDeviceChange 函数,其详细实现步骤有,一,在对应的 xxxdlg.h 文件中加入 

afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD_PTR dwData);  二,在xxxdlg.cpp 文件中实现 OnDeviceChange 函数功能:

PDEV_BROADCAST_DEVICEINTERFACE pdbi;
PDEV_BROADCAST_PORT dhr;
DEV_BROADCAST_DEVICEINTERFACE* dbd;
 //设备状态改变时的处理函数
 BOOL CServoTestDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData)
 {
	
	 dbd = (DEV_BROADCAST_DEVICEINTERFACE*) dwData;
	 //dwData是一个指向DEV_BROADCAST_DEVICEINTERFACE结构体的指针,
	 //在该结构体中保存了设备的类型、路径名等参数。通过跟我们指定设备
	 //的路径名比较,即可以判断是否是我们指定的设备拔下或者插入了。
	pdbi = (PDEV_BROADCAST_DEVICEINTERFACE)dwData;
    dhr  = (PDEV_BROADCAST_PORT )dwData;

	 switch (nEventType) //参数nEventType中保存着事件的类型
	 {
		 //设备连接事件
	 case DBT_DEVICEARRIVAL:
		 if (pdbi->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
		 {
			 PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)dhr;
			 CString name(lpdbv->dbcp_name); 
			 if ( name.Find(L"VID_0483") &&  name.Find(L"PID_5740") )
			 {
				 // OnBnClickedConnectDevice();  // 插入后在操作
			 }
		 }
		 return TRUE;

		 // 设备拔出事件
	 case DBT_DEVICEREMOVECOMPLETE:
		 if (pdbi->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
		 {
			 PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)dhr;
			 CString name(lpdbv->dbcp_name);
			 if ( name.Find(L"VID_0483") &&  name.Find(L"PID_5740") )
			 {
				 if (IsDeviceOpened == TRUE )
				 {
					 // OnBnClickedReleaseDevice(); // 拔出后的操作
				 }
			 }
		 }
		 return TRUE;

	 default: return TRUE;
	 }
 }

上面的代码加入了对usb 设备的VID 与 PID的判定,以确定是否是所关心的设备的插入/拔出。

实现以上三步,就可以实现设备的热插拔功能了!!

猜你喜欢

转载自blog.csdn.net/zhanglifu3601881/article/details/85113815
今日推荐