.
第一步:列举所有的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;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;i 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. 因篇幅问题不能全部显示,请点此查看更多更全内容