📄 hid_recv.cpp
字号:
#include "stdafx.h"
#include <stdio.h>
#include "resource.h"
extern "C"
{
#include "setupapi.h"
#include "hidsdi.h"
}
#pragma comment(lib,"setupapi")
#pragma comment(lib,"hid")
#define MAX_DATA_LEN 1024
#define RECV_DATA_LEN 1024
HWND MainHwnd;
HANDLE hThread,hThread1;
HANDLE hidHandle;
BOOL stop;
void OnLink();
void OnCut();
void RecvThreadFunction(HANDLE hidHandle);
void SendThreadFunction(HANDLE hidHandle);
void Clr();
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
return DialogBox(hInstance, (LPCTSTR)IDD_Main, 0, (DLGPROC)WndProc);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
MainHwnd=hWnd;
switch (message)
{
case WM_INITDIALOG: //初始化
hidHandle=INVALID_HANDLE_VALUE;
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDC_Link: //连接
OnLink();
break;
case IDC_Cut: //断开
stop=1;
OnCut();
break;
case IDC_Recv: //接收
stop=0; //停止接受标志为0
//创建接受线程,失败则报错
hThread=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)RecvThreadFunction,NULL,0,NULL);
if(hThread==INVALID_HANDLE_VALUE)
MessageBox(NULL,"启动接收数据线程失败!","Greetings",0);
else
EnableWindow(GetDlgItem(MainHwnd,IDC_Recv),FALSE);
break;
case IDC_SEND:
stop=0; //停止接受标志为0
//创建发送线程,失败则报错
hThread1=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)SendThreadFunction,NULL,0,NULL);
if(hThread1==INVALID_HANDLE_VALUE)
MessageBox(NULL,"启动接收数据线程失败!","Greetings",0);
else
EnableWindow(GetDlgItem(MainHwnd,IDC_SEND),FALSE);
break;
case IDC_Clear: //清除接受框内容
Clr();
break;
case IDC_Stop: //停止接受
stop=1;
EnableWindow(GetDlgItem(MainHwnd,IDC_SEND),TRUE);
EnableWindow(GetDlgItem(MainHwnd,IDC_SEND),TRUE);
break;
case WM_DESTROY:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return 0;
}
void OnLink()
{
int USB_VID,USB_PID;
int deviceNo=0;
ULONG m_MaxDataLen;
char tem[100]="";
USB_VID=0x5131; // 0x5131 0x413c; //厂商ID
USB_PID=0x2007; // 0x2007 0x2003; //设备ID
GUID hidGuid;
SP_DEVICE_INTERFACE_DATA devInfoData;
if(hidHandle!=INVALID_HANDLE_VALUE)
{
sprintf(tem,"设备已连接!");
SetWindowText(GetDlgItem(MainHwnd,IDC_Status),tem);
return;
}
HidD_GetHidGuid(&hidGuid);//取得HID类别的GUID
HDEVINFO hDevInfo=SetupDiGetClassDevs(&hidGuid,NULL,NULL,
(DIGCF_PRESENT|DIGCF_DEVICEINTERFACE));//获取HID设备信息
if(!hDevInfo)//失败则报错
{
sprintf(tem,"获取HID设备信息失败!");
SetWindowText(GetDlgItem(MainHwnd,IDC_Status),tem);
return;
}
devInfoData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
SetLastError(NO_ERROR);
while(GetLastError()!=ERROR_NO_MORE_ITEMS)
{
if(SetupDiEnumInterfaceDevice (hDevInfo,0,&hidGuid,deviceNo,&devInfoData))//识别HID接口
{
ULONG requireLength=0;
SetupDiGetInterfaceDeviceDetail(hDevInfo,&devInfoData,NULL,0,&requireLength,NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail=
(SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc (requireLength);
devDetail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
//获取设备路径
if(!SetupDiGetInterfaceDeviceDetail(hDevInfo,&devInfoData,devDetail,requireLength,NULL,NULL))
{
MessageBox(NULL,"获取HID设备细节信息失败!","Greetings",0);
free(devDetail);
return;
}
//打开设备,并获得设备句柄
hidHandle=CreateFile(devDetail->DevicePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
ULONG i = GetLastError();
//循环直到找到可以访问的设备
if(hidHandle==INVALID_HANDLE_VALUE)
{
deviceNo++;
continue;
}
_HIDD_ATTRIBUTES hidAttributes;
//获取厂商ID和设备ID
if(!HidD_GetAttributes(hidHandle,&hidAttributes))
{
CloseHandle(hidHandle);
deviceNo++;
continue;
}
//如是要找的设备,则显示设备已连接
if(USB_VID==hidAttributes.VendorID && USB_PID==hidAttributes.ProductID)
{
char version[100]="";
sprintf(version,"设备已连接,ver%X",hidAttributes.VersionNumber);
SetWindowText(GetDlgItem(MainHwnd,IDC_Status),version);
m_MaxDataLen=MAX_DATA_LEN;
break;
}
else//如不是要找的设备,则关闭此设备,再循环查找设备
{
CloseHandle(hidHandle);
deviceNo++;
}
}
}
//设备未连接,则显示
if(hidHandle==INVALID_HANDLE_VALUE)
{
sprintf(tem,"设备未连接!");
SetWindowText(GetDlgItem(MainHwnd,IDC_Status),tem);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
void RecvThreadFunction(LPVOID lpParameter )
{
// char msg[100];
char *recvDataBuf=new char[RECV_DATA_LEN];
// COMMTIMEOUTS m_time;
DWORD recvdBytes,Result;
HANDLE hEventObject;
PHIDP_PREPARSED_DATA PreparsedData;
HIDP_CAPS Capabilities;
BOOL i;
i=1;
bool flag=FALSE;
OVERLAPPED HIDOverlapped;
hEventObject=CreateEvent(NULL,TRUE,TRUE,"");
HIDOverlapped.hEvent=hEventObject;
HIDOverlapped.Offset=0;
HIDOverlapped.OffsetHigh=0;
if(hidHandle==INVALID_HANDLE_VALUE)
{
char tem[100];
sprintf(tem,"设备尚未连接!");
SetDlgItemText (MainHwnd, IDC_RecvEdit, tem);
return;
}
if(!HidD_GetPreparsedData(hidHandle,&PreparsedData))
{
ULONG tang=GetLastError();
char tem[100];
sprintf(tem,"Could not get HID preparsed data!");
SetDlgItemText (MainHwnd, IDC_RecvEdit, tem);
}
NTSTATUS status=HidP_GetCaps(PreparsedData, &Capabilities);
while(!stop)
{
ResetEvent(hEventObject);
Result=ReadFile(hidHandle, recvDataBuf,Capabilities.InputReportByteLength,
&recvdBytes,(LPOVERLAPPED)&HIDOverlapped); //接收数据 (LPOVERLAPPED)&HIDOverlapped
ULONG tang=GetLastError();
Result=WaitForSingleObject(hEventObject,1000);
if(Result==WAIT_TIMEOUT||Result==WAIT_ABANDONED)//如超时返回则取消操作
{
CancelIo(&hidHandle);
i=0;
}
if(i==1)//不是超时返回则显示数据
{
CHAR tem[180000]="",tem2[20]="";
sprintf(tem2,"%02X %02X %02X %02X %02X %02X ",(UCHAR)recvDataBuf[2],(UCHAR)recvDataBuf[3],(UCHAR)recvDataBuf[4],(UCHAR)recvDataBuf[5],(UCHAR)recvDataBuf[6],(UCHAR)recvDataBuf[7]);
if(!flag)
GetDlgItemText(MainHwnd,IDC_RecvEdit,tem,180000);
else
{
SetDlgItemText (MainHwnd, IDC_RecvEdit,"");
flag=FALSE;
}
strcat(tem,tem2);
SetDlgItemText (MainHwnd, IDC_RecvEdit, tem);
ULONG you=strlen(tem);
if(you==180000)
{
ZeroMemory(tem,180000);
flag=TRUE;
}
}
i=1;
Sleep(1);
}
if(stop)
EnableWindow(GetDlgItem(MainHwnd,IDC_Recv),TRUE);
delete recvDataBuf;
return;
}
void Clr()//清除接收文本框的内容
{
SetDlgItemText (MainHwnd, IDC_RecvEdit,"");
return;
}
void OnCut()
{
char tem[100]="";
if(hThread != INVALID_HANDLE_VALUE){ //关闭接收线程句柄
CloseHandle(hThread);
hThread = INVALID_HANDLE_VALUE;
}
if(hidHandle!=INVALID_HANDLE_VALUE) //关闭设备
{
CloseHandle(hidHandle);
hidHandle=INVALID_HANDLE_VALUE;
sprintf(tem,"设备已断开!");
SetWindowText(GetDlgItem(MainHwnd,IDC_Status),tem);
}
else
{
sprintf(tem,"设备未连接!");
SetWindowText(GetDlgItem(MainHwnd,IDC_Status),tem);
}
return;
}
void SendThreadFunction(LPVOID lpParameter)
{
ULONG OutputReportLen=0;
ULONG UsageLength = 0;
PHIDP_PREPARSED_DATA PreparsedData;
HANDLE hEventObject;
DWORD SendBytes=0,Result;
HIDP_CAPS Capabilities;
NTSTATUS status;
BOOL i=1;
bool flag=FALSE;
OVERLAPPED HIDOverlapped;
hEventObject=CreateEvent(NULL,TRUE,TRUE,"");
HIDOverlapped.hEvent=hEventObject;
HIDOverlapped.Offset=0;
HIDOverlapped.OffsetHigh=0;
USAGE UsageList[3];
UsageList[0]=0;
UsageList[1]=0;
UsageList[2]=0;
if(hidHandle==INVALID_HANDLE_VALUE)
{
char tem[100];
sprintf(tem,"设备尚未连接!");
SetDlgItemText (MainHwnd, IDC_RecvEdit, tem);
return;
}
if(!HidD_GetPreparsedData(hidHandle,&PreparsedData))
{
ULONG tang=GetLastError();
char tem[100];
sprintf(tem,"Could not get HID preparsed data!");
SetDlgItemText (MainHwnd, IDC_RecvEdit, tem);
}
status=HidP_GetCaps(PreparsedData, &Capabilities);
OutputReportLen=Capabilities.OutputReportByteLength;
char * OutputReport = new char[OutputReportLen];
ZeroMemory(OutputReport,OutputReportLen);
OutputReport[0]=0x02;
OutputReport[1]=0x06;
OutputReport[2]=0x08;
status = HidP_SetButtons( HidP_Output, HID_USAGE_PAGE_GENERIC, 0,
UsageList, &UsageLength, PreparsedData, OutputReport, OutputReportLen);
if( status!=HIDP_STATUS_SUCCESS)
{
delete OutputReport;
return;
}
while(!stop)
{
ResetEvent(hEventObject);
Result=WriteFile(hidHandle, OutputReport,OutputReportLen,
&SendBytes, (LPOVERLAPPED)&HIDOverlapped); //接收数据
Result=GetLastError();
Result=WaitForSingleObject(hEventObject,1000);
if(Result==WAIT_TIMEOUT||Result==WAIT_ABANDONED)//如超时返回则取消操作
{
CancelIo(&hidHandle);
i=0;
}
if(i==1)//不是超时返回则显示数据
{
CHAR tem[180000]="",tem2[20]="";
sprintf(tem2,"%02X %02X %02X %02X %02X %02X ",(UCHAR)OutputReport[2],(UCHAR)OutputReport[3],(UCHAR)OutputReport[4],(UCHAR)OutputReport[5],(UCHAR)OutputReport[6],(UCHAR)OutputReport[7]);
if(!flag)
GetDlgItemText(MainHwnd,IDC_RecvEdit,tem,180000);
else
{
SetDlgItemText (MainHwnd, IDC_RecvEdit,"");
flag=FALSE;
}
strcat(tem,tem2);
SetDlgItemText (MainHwnd, IDC_RecvEdit, tem);
ULONG you=strlen(tem);
if(you==180000)
{
ZeroMemory(tem,180000);
flag=TRUE;
}
}
i=1;
if(OutputReport[2]==0xff)
OutputReport[2]=0x00;
else if(OutputReport[3]==0xff)
OutputReport[3]=0x00;
else if(OutputReport[4]==0xff)
OutputReport[4]=0x00;
else if(OutputReport[5]==0xff)
OutputReport[5]=0x00;
else if(OutputReport[6]==0xff)
OutputReport[6]=0x00;
else if(OutputReport[7]==0xff)
OutputReport[7]=0x00;
OutputReport[2]++;
OutputReport[3]++;
OutputReport[4]++;
OutputReport[5]++;
OutputReport[6]++;
OutputReport[7]++;
}
if(stop)
EnableWindow(GetDlgItem(MainHwnd,IDC_SEND),TRUE);
delete OutputReport;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -