C++ MFC界面读写USB HID设备数据程序 发一个简单易用的界面,用来对USB HID设备(比如说游戏手柄,控制面板等)读写数据,一般情况下面板上有一些LED,可以帮助我们测试读写是否正确。另外,需要可以修改vendorID和prodcutID,这样一个界面,可以用于测试多个HID设备。

过程分成3步:1: 列举出所有的HID设备,2: 循环读取HID设备数据,3: 向HID设备写数据,下面我把三部分的程序单独分开,方便大家学习!

在讲具体程序之前,先说一下visual studio的环境配置(我用的是2008版本)!
<下面程序需要包含DDK一部分头文件和库文件>

第一步:列举所有的HID设备:


```cpp
m_ctllHIDdevices.ResetContent(); //这是MFC里面一个list控件,用来显示所有的HID设备的,如果你没有界面,可以不需要此行
UpdateData(FALSE); //更新界面
CString temp;
int Count = 0; //Total number of devices found
DWORD strSize=0,requiredSize=0;
BOOL result1,result2;
ULONG DeviceInterfaceDetailDataSize;
//定义一些变量,以后会用到
SP_DEVINFO_DATA DeviceInfoData;
SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
//PSP_DEVICE_INTERFACE_DETAIL_DATA test;
//第一步:获取deviceID
GUID deviceId;
HidD_GetHidGuid(&deviceId);//第二步:获取设备信息
HDEVINFO handle;
handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devices//第三步:对所有的设备进行枚举
//SetupDiEnumDeviceInterfaces();
result1=false; //定义一些变量
result2=false;
CString temp11="";
do
{DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);result1 = SetupDiEnumDeviceInterfaces(handle,NULL, // IN PSP_DEVINFO_DATA  DeviceInfoData,  OPTIONAL&deviceId,Count,&DeviceInterfaceData);//获得设备详细数据(初步)SetupDiGetDeviceInterfaceDetail(handle,&DeviceInterfaceData,NULL,0,&strSize,NULL);requiredSize=strSize;DeviceInterfaceDetailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);DeviceInterfaceDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);DeviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA);//再次获得详细数据result2=SetupDiGetDeviceInterfaceDetail(handle,&DeviceInterfaceData,DeviceInterfaceDetailData,strSize,&requiredSize,&DeviceInfoData);//获得设备路径(最重要的部分)temp=DeviceInterfaceDetailData->DevicePath;UpdateData(FALSE);m_ctllHIDdevices.AddString(temp);Count++;} while (result1);UpdateData(false);到这个时候为止,所有的设备路径,都会显示在窗口的listbox里面!第二步:循环读取HID设备数据(根据用户提供的HID的vendorID和productID),并且把字节解码成二进制,在MFC界面上用LED展示:为了不影响主线程的运行,我把读取数据的操作,放在一个子线程里!每隔50ms去读取一次数据!首先创建一个线程:HANDLE hThread1;bStopHID=false; //这个变量,以后用来停止线程UpdateData(true); //更新界面,获取变量UpdateData(false);hThread1 = CreateThread(NULL,0,Thread_Enable_Read,(LPVOID)this, NULL, NULL);在线程的程序里:CusbhidDlg *p = ( CusbhidDlg *)pvParam; //获取主窗口的指针,用来调用主窗口的变量和函数p->UpdateData(true);p->bStopHID=false;CString temp;CString DevicePath;temp="";int Count = 0; //Total number of devices foundDWORD strSize=0,requiredSize=0;BOOL result1,result2;ULONG DeviceInterfaceDetailDataSize;        SP_DEVINFO_DATA DeviceInfoData;SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData;PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;//PSP_DEVICE_INTERFACE_DETAIL_DATA test;//1GUID deviceId;HidD_GetHidGuid(&deviceId);int venderID=p->v_eVendorID; //从窗口里获取用户输入的VendorIDint productID=p->v_eProductID;//从窗口里获取用户输入的ProductIDunsigned char inbuffer[2]; //用来存放读取的数据,请在这里定义你自己需要的长度,我每次读一个字节进来unsigned long numBytesReturned;HIDD_ATTRIBUTES devAttr;PHIDP_PREPARSED_DATA PreparsedData;HIDP_CAPS Capabilities;int readValue;bool LED;int flag=0;//2HDEVINFO handle;handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devicesint i=0;int j=p->m_ctllHIDdevices.GetCount();for (i=0;i<p->m_ctllHIDdevices.GetCount();i++){p->m_ctllHIDdevices.GetText(i,temp);DevicePath=temp;//CreateFile是非常重要的一步,用来建立于HID通信的句柄HANDLE hCom = CreateFile (DevicePath,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING, 0,NULL);if (hCom == INVALID_HANDLE_VALUE){             //AfxMessageBox("Invalide Device Path...");continue;}devAttr.Size=sizeof(HIDD_ATTRIBUTES);if (!HidD_GetAttributes(hCom,&devAttr)){CloseHandle(hCom);AfxMessageBox("Cannot get the parameters of the HID...");return 0;   }//temp.Format("Vendor ID: %d, Product ID:%d",devAttr.VendorID,devAttr.ProductID); //Compare with the Vendor ID and Product ID from Nakamura-san//AfxMessageBox(temp);if (!HidD_GetPreparsedData(hCom,&PreparsedData)){CloseHandle(hCom);AfxMessageBox("Cannot get the Preparsed Data...");return 0;   }if(!HidP_GetCaps(PreparsedData,&Capabilities)){CloseHandle(hCom);AfxMessageBox("Cannot get the Cap Data...");return 0;   }if (devAttr.VendorID == venderID && devAttr.ProductID == productID) {while(1){result1 = ReadFile(hCom, &inbuffer[0], Capabilities.InputReportByteLength, &numBytesReturned, 0);temp=inbuffer;//p->m_eDataRead=CString(inbuffer);//p->UpdateData(false);if(!result1){AfxMessageBox("Cannot Read Data...");return 0;   }readValue=inbuffer[1];p->m_eDataRead.Format("%d",readValue);//下面是我把数据从10进制转换成二进制,并且点亮LED (一个字节有8个bits,可以点亮8个LEDfor (int k=0;k<8;k++){flag=readValue%2;readValue=readValue/2;        if (k==0){if (flag==0)p->m_sDynLED0.SwitchOff();elsep->m_sDynLED0.SwitchOn();}else if (k==1){if (flag==0)p->m_sDynLED1.SwitchOff();elsep->m_sDynLED1.SwitchOn();}else if (k==2){if (flag==0)p->m_sDynLED2.SwitchOff();elsep->m_sDynLED2.SwitchOn();}else if (k==3){if (flag==0)p->m_sDynLED3.SwitchOff();elsep->m_sDynLED3.SwitchOn();}else if (k==4){if (flag==0)p->m_sDynLED4.SwitchOff();elsep->m_sDynLED4.SwitchOn();}else if (k==5){if (flag==0)p->m_sDynLED5.SwitchOff();elsep->m_sDynLED5.SwitchOn();}else if (k==6){if (flag==0)p->m_sDynLED6.SwitchOff();elsep->m_sDynLED6.SwitchOn();}else if (k==7){if (flag==0)p->m_sDynLED7.SwitchOff();elsep->m_sDynLED7.SwitchOn();}}p->UpdateData(false);::Sleep(50);//判断用户是否点击停止按钮,若是,则退出if(p->bStopHID) {AfxMessageBox("stopped...");return 0;}}}}if (i==j){AfxMessageBox("There is no such HID device...");}return 0;第三步:向HID设备写数据(根据用户提供的HID的vendorID和productID),用户输入的是二进制数据:与读的程序一样,唯一区别就是红色那部分!UpdateData(true);
bStopHID=false;CString temp;
CString DevicePath;
temp="";
int Count = 0; //Total number of devices found
DWORD strSize=0,requiredSize=0;
BOOL result1,result2;
ULONG DeviceInterfaceDetailDataSize;
SP_DEVINFO_DATA DeviceInfoData;
SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
//PSP_DEVICE_INTERFACE_DETAIL_DATA test;
//1
GUID deviceId;
HidD_GetHidGuid(&deviceId);int venderID=v_eVendorID;
int productID=v_eProductID;unsigned char inbuffer[2];
unsigned long numBytesReturned;
HIDD_ATTRIBUTES devAttr;
PHIDP_PREPARSED_DATA PreparsedData;
HIDP_CAPS Capabilities;
int readValue;
bool LED;
int flag=0;
inbuffer[0]=0;
//把界面里的二进制转换成10进制
inbuffer[1]=m_eByte0*1+m_eByte1*2+m_eByte2*4+m_eByte3*8+m_eByte4*16+m_eByte5*32+m_eByte6*64+m_eByte7*128;v_eDataToWrite=inbuffer[1];
UpdateData(false);//2
HDEVINFO handle;
handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devices
int i=0;
int j=m_ctllHIDdevices.GetCount();
for (i=0;i<m_ctllHIDdevices.GetCount();i++)
{m_ctllHIDdevices.GetText(i,temp);DevicePath=temp;HANDLE hCom = CreateFile (DevicePath,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING, 0,NULL);if (hCom == INVALID_HANDLE_VALUE){             //AfxMessageBox("Invalide Device Path...");continue;}devAttr.Size=sizeof(HIDD_ATTRIBUTES);if (!HidD_GetAttributes(hCom,&devAttr)){CloseHandle(hCom);AfxMessageBox("Cannot get the parameters of the HID...");return;   }//temp.Format("Vendor ID: %d, Product ID:%d",devAttr.VendorID,devAttr.ProductID); //Compare with the Vendor ID and Product ID from Nakamura-san//AfxMessageBox(temp);if (!HidD_GetPreparsedData(hCom,&PreparsedData)){CloseHandle(hCom);AfxMessageBox("Cannot get the Preparsed Data...");return;   }if(!HidP_GetCaps(PreparsedData,&Capabilities)){CloseHandle(hCom);AfxMessageBox("Cannot get the Cap Data...");return;   }// Write Fileif (devAttr.VendorID == venderID && devAttr.ProductID == productID) {result1 = WriteFile(hCom, inbuffer, 2, &numBytesReturned, NULL);//temp=inbuffer;//p->m_eDataRead=CString(inbuffer);//p->UpdateData(false);if(!result1){AfxMessageBox("Cannot Write Data...");return;   }AfxMessageBox("Suncess...");break;}
}
if (i==j)
{AfxMessageBox("There is no such HID device...");
}
return;

C++ MFC界面读写USB HID设备数据程序相关推荐

  1. 实践 C++ MFC界面读写USB HID设备数据程序

    在开发了一个多线程USB烧写程序后,得到新的任务,要将HID的内容放到里面,没有人带着做细致的讲解,靠自己自生自灭: 1, 什么是HID? (项目要的急,没有什么了解就开始了!只知道,在Windows ...

  2. USB HID设备数据的读取

    https://blog.csdn.net/DFSAE/article/details/81876573 USB设备(HID) Android下获取HID数据的方式: 1.通过读取/dev/hidra ...

  3. hid python uhf_简单的读写Python中的USB HID设备?

    我有一个相当简单的USB HID设备,我一直在试图弄清楚如何读取和写入使用Python.我已经能够使用PyWinUSB从它读取,但是当我尝试写入它时,问题就出现了.试图写入它会使事情爆炸.简单的读写P ...

  4. 嵌入式linux作为hid设备,基于嵌入式系统的USB(HID)设备

    基于嵌入式系统的USB(HID)设备 目前嵌入式系统在数字化电子产品领域应用越来越广泛.随着其成本的降低,大有取代单片机的趋势. USB设备以其小巧.便携.即插即用.成本低廉等优势在当前的桌面应用中有 ...

  5. USB HID 设备类协议入门

    一.应用场合 USB HID类是比较大的一个类,HID类设备属于人机交互操作的设备.用于控制计算机操作的一些方面,如USB鼠标,USB键盘,USB游戏操纵杆,USB触摸板,USB轨迹球.电话拨号设备. ...

  6. C# 访问USB(HID)设备方法一

    这几天捣腾C# 访问USB(HID)设备的方式,看了好多资料,发现有两种方式访问USB设备,废话少说直接看核心代码 h = Win32Wrapper.SetupDiGetClassDevs(IntPt ...

  7. c# hid usb 卡死_C# 访问USB(HID)设备

    //代码暂时没有整理,传入参数是设备序号,//有些USB设备其实有很多HID设备,就是一个接口上有几个设备,这个时候需要//用index++来逐个循环,直到获取设备返回false后,跳出去,把获取的设 ...

  8. hid设备驱动linux,linux usb hid设备驱动(3)

    本文分析了蓝牙bluez协议栈中HID协议的实现. 1. 基本概念 HID协议用于人机输入设备.Bluez中关于HID的实现代码在其根目录下的input目录.蓝牙规范中包含关于HID的profile, ...

  9. USB HID设备报告描述符详解

    概述: 报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明. USB通讯协议的规范是以1ms产生一个USB帧(Frame),USB设备可 ...

最新文章

  1. 注册界面翻译_B站UP主自制的开源OCR翻译器走红Github,用一次就粉了
  2. python+selenium自动化测试——浏览器驱动
  3. 荣耀v9系统升级 服务器,荣耀V9首次系统升级 带来一个有意思的新功能
  4. c# 读取 txt 文件中数据(int)
  5. this指向问题(2)
  6. Memory Notification: Library Cache Object loaded into SGA问题
  7. 成为软件高手的几个忌讳(转贴)
  8. 中国非制式爆炸物薄膜传感器研究取得进展
  9. 《简明Python教程》学习笔记
  10. 耳机插入电脑的,耳机接口,却没有声音的 解决方法
  11. 免备案去掉端口号访问网站
  12. 哪里有免费的ASP空间?
  13. 2021-07-19支付宝扫码点餐推广怎么做(干货来了)
  14. java 怎么让图片运动,小编给你传授java怎么实现键盘控制图片移动
  15. 深耕“有效私域”,雀巢集团携手腾讯重塑零售数字化体验
  16. 瑞吉外卖项目剩余功能补充
  17. java好学么_java是什么好学吗
  18. [ 重 新 预 习 ] Node.js搭建服务
  19. 自制手机app的51蓝牙+WiFi+循迹+避障OLED显示速度小车
  20. 企业网站建设的要求及策划

热门文章

  1. querySelector
  2. 【Notes】《Thinking in Java》【Chapter 11】Part II
  3. 如何获得阿里技术offer:从《阿里DBA面试题》体味阿里社会招聘
  4. 算法学习之百钱买百鸡
  5. Linux+Apache+Postgresql+PHP安装Drupal7.15
  6. 文本比较算法Ⅲ——计算文本的相似度
  7. ABCpdf.NET 的简易使用指南
  8. MySQL binlog日志
  9. laravel artisan
  10. 初探 Unix 操作系统