⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hid_recv.cpp

📁 ch372 hid通讯代码 包含 pc机和设备的程序
💻 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 + -