C++MFC界面读写USBHID设备数据程序.docx
《C++MFC界面读写USBHID设备数据程序.docx》由会员分享,可在线阅读,更多相关《C++MFC界面读写USBHID设备数据程序.docx(16页珍藏版)》请在冰豆网上搜索。
C++MFC界面读写USBHID设备数据程序
第一步:
列举所有的HID设备:
m^ctllHIDdevices.ResetContentO;〃这是MFC里面一个list控件,用来显示所有的HID设备的,如果你没有界而,可以不需要此行
UpdateData(FALzSE);〃更新界而
CStringtemp;
intCount=0;//Totalnumberofdevicesfound
DWORDstrSize=O,requiredSize=O;
BOOLresultl,result2;
ULONGDevicelnterfaceDctailDataSize;
〃定义一些变虽.以后会用到
SP_DEVINFO_D/CTADevicelnfoData;
SP_DEVICE_INTERFACE_DATADeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATADeviceInterfaceDctailData;//PSP_DEVICE_INTERFACE_DETAIL_DATAtest:
〃第一步:
获取devicelD
GUIDdeviceld;
HidD_GetHidGuid(&dcviccld);
〃第二步:
获取设备信息
HDEVINFOhandle;
handle=SetupDiGetCIassDevs(&dcviccld,NULL,NULL,DIGCF_DEVICEINTERFACEIDIGCF_PRESENT);//GetonlyHIDdevices
〃第三步:
对所有的设备进行枚举//SetupDiEnumDevicelnterfacesO;resultl=false;〃左义一些变虽:
result2=false;
CStringtempil=n,;
do
DevicelntcrfaccData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);result1=SctupDiEnumDcviceInterfaces(
handle,
NULL.//INPSP_DEVINFO_DATADevicelnfoData.OPTIONAL
&deviceld・
Count,
&DcvicelnterfaceData
);
〃获得设备详細数据(初步)
SetupDiGetDeviceInterfaceDctail(handle,
&DevicelnterfaceData,
NULL,
0,
&strSize,
NULL);
requiredSize=strSize;
DeviceIntcrfaccDctailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malIoc(requircdSize);
DeviceInterfaceDctailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
DeviceInfoData.cbSize=s第一步:
列举所有的HID设备:
ni_ctllHIDdevices.ResetContent();〃这是MFC里而一个list控件,用来显示所有的HID设备的,如果你没有界而,可以不需要此行
UpdateData(FALSE);〃更新界而
CStringtemp;
intCount=0;//Totalnumberofdevicesfound
DWORDstrSize=O,requiredSize=O;
BOOLresultl,result2;
ULONGDevicelnterfaceDctailDataSize;
〃圮义一些变量,以后会用到
SP_DEVINFO_DATADevicelnfoData;
SP_DEVICEJNTERFACE_DATADeviceInterfaceData;
PSP_DEVICEJNTERFACE_DETAIL_DATADcviceInterfaceDctailData;
//PSP_DEVICEJNTERFACE_DETAIL_DATAtest;
〃第一步:
获取devicelD
GUIDdeviceld;
HidD_GetHidGuid(&dcviccld);
〃第二步:
获取设备信息
HDEVINFOhandle;
handle=ScmpDiGetClassDevs(&dcviccld,NULL,NULL,DIGCF.DEVICEINTERFACEIDIGCF_PRESENT):
//GetonlyHIDdevices
〃第三步:
对所有的设备进行枚举//SetupDiEnumDcvicelntcrfacesO;resultl=false;〃左义一些变量result2=false;
CStringtempi
do
DevicelnterfaceData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);result!
=SetupDiEnumDeviceInterfaces(
handle.
NULL,//INPSP_DEVINFO_DATADevicelnfoData,OPTIONAL
&deviceld.
Count,
&DevicelnterfaceData
);
〃获得设备详细数据(初步)
SctupDiGetDeviceInterfaceDetail(handle,
&DevicelnterfaceData,
NULL,
0,
&strSize,
NULL);
requiredSize=strSize;
DeviceInterfaceDctailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requircdSize);
DeviceInterfaceDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
DeviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
〃再次获得详细数据
result2=SetupDiGetDeviccInterfaceDetail(handle,
&DevicelnterfaceData,
DevicelnterfaceDctailData,
strSize,
&requiredSize,
&DevicelnfoData);
//获得设备路径(最重要的部分)
temp=DeviccInterfaccDctailData->DcvicePath:
UpdateData(FALSE);
m_ctllHIDdevices.AddString(temp);
Count++;
)while(result1);
UpdateData(false);izeof(SP_DEVINFO_DATA);
〃再次获得详細数据
result2=SetupDiGetDeviceInterfaceDetail(handle5
&DevicelnterfaceData,
DevicelnterfaceDctailData.
strSize,
&requiredSize,
&DcvicelnfoData);
〃获得设备路径(最重要的部分)
temp=DeviccInterfaccDctailData->DevicePath:
UpdateData(FALSE);
m_ctllHIDdevices.AddString(temp);
Count++;
)while(result1);
UpdateData(false);
第二步:
循环读取HID设备数据(根据用户提供的HID的vendorlD和productID),并且把字节解码成二进制,在MFC界而上用LED展示:
为了不影响主线程的运行,我把读取数据的操作,放在一个子线程里!
每隔50ms去读取一次数据!
首先创建一个线程:
HANDLEhThreadl;
bStopHID=falsc;//这个变量,以后用来停止线程
UpdateData(true);〃更新界而,获取变捲
UpdateData(false);
hThrcadl=CreateTliread(NULUO.Thread_Enable_Read.(LPVOID)this,NULL,NULL);
在线程的程序里:
CusbhidDlg*p=(CusbhidDlg*)pvParam:
〃获取主窗口的指针,用来调用主窗口的变量和函数
p->UpdateData(true);
p->bStopHID=false;
CStringtemp;
CStringDevicePath;
temp=,M,;
intCount=0;//Totalnumberofdevicesfound
DWORDstrSize=O.requiredSize=O;
BOOLresultLresult2;
ULONGDevicelnterfaceDctailDataSize;
SP_DEVINFO_DATADevicelnfoData;
SP_DEVICE_INTERFACE_DATADeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATADeviceInterfaceDetailData;
//PSPDEVICEINTERFACEDETAILDATAtest:
//I
GUIDdeviceld;
HidD_GetHidGuid(&dcviccld);
intvenderID=p->v_eVendorID;〃从窗「1电获取用丿输入的VendorlD
intproductID=p->v_eProductID;//从窗门里获取用戸输入的ProductID
unsignedcharinbuffer[2];〃用来存放读取的数据,请在这里泄义你自己需要的长度,我每次读一个字节进来
unsignedlongnumBytesReturned;
HIDD.ATTRIBUTESdevAttr;
PHIDP_PREPARSED_DATAPreparsedData;
HIDP.CAPSCapabilities;
intreadValue;
boolLED;
intflag=O;
//2
HDEVINFOhandle;
handle=SetupDiGetClassDevs(&dcviccld,NULL,NULL,DIGCF_DEVICEINTERFACEI
DIGCF_PRESENT);//GetonlyHIDdevices
inti=0;
intj=p->m-ctllHIDdevices.GetCount();
for(i=0;im_ctllHIDdevices.GetCount();i++)
{
p->m_ctllHIDdevices.GetText(i.temp):
DevicePath=temp;
//CreateFile是非常重要的一步,用来建立于HID通信的句柄
HANDLEhCom=CreateFile(
DevicePath.
GENERIC_READIGENERIC_WRITE.
HLE_SHARE_READIFILE_SHARE_WRITE.
NULL.
OPEN_EXISTING0,
NULL);
if(hCom=INVALID_HANDLE_VALUE)
//AfxMessageBoxC'InvalideDevicePath...");
continue;
)
dcvAttr.Size=sizeof(HIDD_ATTRIBUTES);
if(!
HidD_GetAttributes(hCom,&devAttr))
{
CloscHandle(hCom);
AfxMessageBox(wCannotgettheparametersoftheHID..:
);
return0;
)
//temp.Format(HVendorID:
%d.ProductID:
%dH,devAttr.VendorID.devAttr.ProductID);
//ComparewiththeVendorIDandProductIDfromNakamura-san
//AfxMessageBox(temp);
if(!
HidD_GctPreparscdData(hConi,&Prq)arsedData))
{
CloscHandle(hCom);
AfxMessageBox(MCannotgetthePreparsedData...”);
return0;
)
if(!
HidP_GetCaps(PreparsedData./Capabilities))
{
CloseHandle(hCom);
AfxMessageBox(HCannotgettheCapData...");
return0;
}
if(devAttr.VendorlD=venderlD&&devAttr.ProductID==productID)while
(1)
result1=ReadFile(hConL&inbufferJO],Capabilities.InputRcportByteLength,
&numBytesReturncd,0);
temp=inbuffer;
//p->m_eDataRead=CString(inbuffer);
//p->UpdateData(false);
if(!
resultl)
{
AfxMessageBox(HCannotReadData...");
return0;
}
readValue=inbuffer[1];
p->m_eDataRead.Forniat(M%d\readValue);
〃下面是我把数据从10进制转换成二进制,并且点亮LED(一个字肖有8个bits,可以点亮8
个LED
for(intk=0:
kv8;k++)
{
flag=readValue%2;
readValue=readValue/2;
if(k==0)
{
if(flag=O)
p->m_sDynLEDO.SwitchOff();
else
p->m_sDynLEDO.SwitchOn();
}
elseif(k=l)
{
if(flag=O)
p->m_sDynLEDl.SwitchOff();
else
p->m_sDynLED1.SwitchOnO;
elseif(k==2)
{
if(flag=O)
p->m_sDynLED2.SwitchOff();elsep->m_sDynLED2.SwitchOn();
elseif(k==3)
{
if(flag=O)
p->m.sDynLED3.SwitchOff();
else
p->m_sDynLED3.SwitchOnO;
}
elseif(k==4)
{
if(flag=O)
p->m_sDynLED4.SwitchOff();else
p->m_sDynLED4.SwitchOn();
}
elseif(k==5)
{
if(flag=O)
p->m_sDynLED5.SwitchOff();
else
p->ni-sDynLED5.SwitchOn();
elseif(k==6)
{
if(flag=O)
p->m_sDynLED6.SwitchOff();else
p->nvsDynLED6.SwitchOn();
)
elseif(k=7)
{
if(flag=O)
p・>m_sDynLED7.SwitchOff();else
p・>m_sDynLED7.SwitchOn();
}
}
p->UpdateData(false);
:
:
Sleep(50);
〃判断用户是否点击停止按钮,若是,则退出if(p->bStopHID)
{
AfxMessageBox(vstopped...,r);
return0;
)
}
}
}
if(i=j)
{
AfxMessageBox("ThereisnosuchHIDdevice...");
}return0;
第三步:
向HID设备写数据(根据用户提供的HID的vendorlD和productID),用户输入的是二进制数据:
与读的程序一样,唯一区别就是红色那部分!
UpdateData(truc);
bStopHID=false;
CStringtemp;
CStringDevicePath;
temp=,H,;
intCount=0;//Totalnumberofdevicesfound
DWORDstrSize=O.requiredSize=O;
BOOLresultl,result2;
ULONGDevicelnterfaceDctailDataSize;
SP_DEVINFO_DATADevicelnfoData;
SP_DEVICE_INTERFACE_DATADcviceInterfaceData;
PSP_DEVICEJNTERFACE_DETAIL_DATADeviceInterfaceDetailData;
//PSP_DEVICEJNTERFACE_DETAIL_DATAtest:
//I
GUIDdeviceld;
HidD_GetHidGuid(&dcviccld);
intvenderID=v_eVendorlD;
intproductID=v_cProductID;
unsignedcharinbuffer[2J;
unsignedlongnumBytesRcturned;
HIDD_ATTRIBUTESdevAttr;
PHIDP_PREPARSED_DATAPreparsedData;
HIDP_CAPSCapabilities;
intreadValue;
boolLED;
intflag=O;
inbuffer[0]=0;
〃把界而里的二进制转换成10进制
inbufferl1]=m_eByteO*1+ni_eByte1*2+nvcByte2*4+m_cByte3*8+in_eByte4*16+m_eByte5*32
+m_cByte6*64+m_cByte7*128;
v_eDataToWrite=inbuffer[1];
UpdateData(false);
//2
HDEVINFOhandle;
handle=ScmpDiGetCIassDevs(&dcviccld,NULL,NULL,DIGCF_DEVICEINTERFACEIDIGCF.PRESENT);//GetonlyHIDdevices
inti=0;
intj=m_ctllHIDdevices.GetCount();
for(i=0;i{
m_ctllHIDdevices.GetText(iJemp);
DevicePath=temp:
HANDLEhCom=CreateFile(
DeviccPath.
GENERIC.READIGENERIC_WRITE.
HLE_SHARE_READIFILE_SHARE_WRITE,
NULL,
OPEN_EXISTING、0.
NULL);
if(hCom=INVALID_HANDLE_VALUE)
{
//AfxMessageBox(MInvaIidcDevicePath../1);
continue;
}
dcvAttr.Size=sizeof(HIDD_ATTRIBUTES);
if(!
HidD_GetAttributes(hCom,&dcvAltr))
{
CloseHandle(hCom);
AfxMessageBox(wCannotgettheparametersoftheHID..:
);
return;
}
//temp.Format("VendorID:
%d.ProductID:
%dM.devAttr.VendorID.devAttr.ProductID);
//ComparewiththeVendorIDandProductIDfromNakamura-san
//AfxMessageBox(temp);
if(!
HidD_GctPrcparsedData(hConi,&PreparsedData))
{
CloscHandle(hCom);
AfxMessageBox(°CannotgetthePreparsedData...11);
return;
}
if(!
HidP_GetCaps(PreparsedData.&Capabilities))
{
CloseHandlc(hCom);
AfxMessageBox(uCannotgettheCapData...0);
return;
}
//WriteFile
if(devAttr.VendorlD=venderlD&&devAttr.ProductID==productID){
resultl=WriteFile(hCom,inbuffer;2,&numBytesReturned,NULL);
//temp=inbuffer;
//p->m_eDataRead=CString(inbuffer);
//p->UpdateData(false);
if(!
resultl)
{
AfxMessageBox(MCannotWriteData...");
return;
)
AfxMessageBox(HSuncess...");
break:
}
}
if(i=j)
{
AfxMessageBox(°ThereisnosuchHIDdevice...n);
}return;