VC++检测硬件设备状态

首先捕捉WM_DEVICECHANGE消息,该消息在usb插拔时均有触发。

MFC下  

添加消息处理函数afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );

添加消息映射BEGIN_MESSAGE_MAP()

...

ON_WM_DEVICECHANGE()

END_MESSAGE_MAP()

Win32 在消息回调处理即可

 

MFC下  nEventType 在没有注册设备的情况下均为7,无法区分,需要设备GUID去注册,方法如下:

 

USB Raw Device/USB设备

{a5dcbf10-6530-11d2   -901f-00c04fb951ed}

Disk Device/磁盘设备

{53f56307-b6bf-11d0   -94f2-00a0c91efb8b}

Network Card/网卡

{ad498944-762f-11d0   -8dcb-00c04fc3358c}

Human Interface Device (HID)/人机界面设备

{4d1e55b2-f16f-11cf    -88cb-001111000030}

Palm/手持设备

{784126bf-4190-11d4   - b5c2-00c04f687a67}

 

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;
  }
}

 

注册代码请在程序初始化时进行,如MFC的OnInitDialog
 
在消息响应中
switch(nEventType)
{
  case DBT_DEVICEARRIVAL://设备可用 
  {
  // PDEV_BROADCAST_DEVICEINTERFACE
  if(lpdb->dbch_devicetype==DBT_DEVTYP_VOLUME)
  {

  PDEV_BROADCAST_VOLUME lpdbv =  (PDEV_BROADCAST_VOLUME)lpdb;
  switch(lpdbv->dbcv_flags)
  {
  dosomething
  }
}
  else if(lpdb->dbch_devicetype==DBT_DEVTYP_DEVICEINTERFACE)
  {
  }
  else
  {
  }
}

 

以上方法较为复杂,需要处理DBT_DEVTYP_VOLUME,DBT_DEVTYP_DEVICEINTERFACE等,现提供一种简单的方法,在DBT_DEVICEARRIVAL有新设备进入时,通过遍历硬件设备变相处理:
//以找usb设备为例,取得的usb盘符放在UsbRoot里面,len为UsbRoot字符数组的长度  

BOOL GetUsbRoot(CHAR* UsbRoot,SHORT len)
{  
  DWORD dwDriveStrLen = 0;  
  CHAR *pDriveName = NULL;  
  UINT Drive = 0;  
  if (UsbRoot == NULL || len <= 0)
  {  
    return FALSE;  
  }   dwDriveStrLen
= ::GetLogicalDriveStrings(0,NULL);//取得你计算机上盘符数目   if (0 == dwDriveStrLen)   {     return FALSE;   }   CHAR *szDriveNameBuff = (CHAR*)malloc(dwDriveStrLen);//根据你机器上的磁盘数目分配内存   if (NULL == szDriveNameBuff)   {     return FALSE;   }   memset(szDriveNameBuff,0,sizeof(szDriveNameBuff));   ::GetLogicalDriveStrings(dwDriveStrLen,szDriveNameBuff);//取得你计算机上所有盘符   pDriveName = szDriveNameBuff;   while (*pDriveName != NULL)//遍历所有盘符,找到你需要的设备   {     Drive = ::GetDriveType(pDriveName);   switch (Drive)   {   case DRIVE_UNKNOWN://未知设备     break;   case DRIVE_NO_ROOT_DIR:     break;   case DRIVE_REMOVABLE://usb设备   //如果为usb,在这里进行相关处理   //break;   case DRIVE_FIXED://硬盘     break;   case DRIVE_REMOTE://网络硬盘,如:局域网服务器上的盘     break;
  case DRIVE_CDROM://光驱     break;   case DRIVE_RAMDISK://RAM 盘     break;   default:     break; }   pDriveName += strlen(pDriveName) + 1; } if(szDriveNameBuff != NULL) {   free(szDriveNameBuff);   szDriveNameBuff = NULL; } return FALSE; }

原文:

VC++实现USB 硬盘等硬件插拔检测

 

 

posted @ 2018-08-20 10:19  余生以学  阅读(1326)  评论(0编辑  收藏  举报