您的当前位置:首页正文

C++MFC界面读写USBHID设备数据程序

2021-03-30 来源:易榕旅网
-

.

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

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,

- .word.zl.

-

.

&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=s第一步:列举所有的HID设备:

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(

- .word.zl.

-

.

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);izeof(SP_DEVINFO_DATA);

//再次获得详细数据

result2=SetupDiGetDeviceInterfaceDetail(handle, &DeviceInterfaceData, DeviceInterfaceDetailData, strSize,

&requiredSize, &DeviceInfoData);

- .word.zl.

-

.

//获得设备路径〔最重要的局部〕

temp=DeviceInterfaceDetailData->DevicePath; UpdateData(FALSE);

m_ctllHIDdevices.AddString(temp); Count++;

} while (result1);

UpdateData(false);

第二步:循环读取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 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;

- .word.zl.

-

.

//1

GUID deviceId;

HidD_GetHidGuid(&deviceId);

int venderID=p->v_eVendorID; //从窗口里获取用户输入的VendorID int productID=p->v_eProductID;//从窗口里获取用户输入的ProductID

unsigned char inbuffer[2]; //用来存放读取的数据,请在这里定义你自己需要的长度,我每次读一个字节进来

unsigned long numBytesReturned; HIDD_ATTRIBUTES devAttr;

PHIDP_PREPARSED_DATA PreparsedData; HIDP_CAPS Capabilities; int readValue; bool LED; int flag=0; //2

HDEVINFO handle;

handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devices int i=0;

int j=p->m_ctllHIDdevices.GetCount();

for (i=0;im_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) {

- .word.zl.

-

.

//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\//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) {

- .word.zl.

-

.

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\

//下面是我把数据从10进制转换成二进制,并且点亮LED (一个字节有8个bits,可以点亮8个LED

for (int k=0;k<8;k++) {

flag=readValue%2;

readValue=readValue/2;

if (k==0) {

if (flag==0)

p->m_sDynLED0.SwitchOff(); else

p->m_sDynLED0.SwitchOn(); }

else if (k==1) {

if (flag==0)

p->m_sDynLED1.SwitchOff(); else

p->m_sDynLED1.SwitchOn(); }

- .word.zl.

-

.

else if (k==2) {

if (flag==0)

p->m_sDynLED2.SwitchOff(); else

p->m_sDynLED2.SwitchOn(); }

else if (k==3) {

if (flag==0)

p->m_sDynLED3.SwitchOff(); else

p->m_sDynLED3.SwitchOn(); }

else if (k==4) {

if (flag==0)

p->m_sDynLED4.SwitchOff(); else

p->m_sDynLED4.SwitchOn(); }

else if (k==5) {

if (flag==0)

p->m_sDynLED5.SwitchOff(); else

p->m_sDynLED5.SwitchOn(); }

else if (k==6) {

if (flag==0)

p->m_sDynLED6.SwitchOff(); else

- .word.zl.

-

.

p->m_sDynLED6.SwitchOn(); }

else if (k==7) {

if (flag==0)

p->m_sDynLED7.SwitchOff(); else

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

- .word.zl.

-

.

第三步:向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

- .word.zl.

-

.

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;im_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\//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...\");

- .word.zl.

-

.

return; }

// Write File

if (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;

- .word.zl.

因篇幅问题不能全部显示,请点此查看更多更全内容