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

📄 hid_recvdlg.cpp

📁 一个对通用HID设备进行操作的例子,在WinXP平台下运行.
💻 CPP
字号:
// HID_RECVDlg.cpp : implementation file
//

#include "stdafx.h"
#include "HID_RECV.h"
#include "HID_RECVDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CHID_RECVDlg dialog

CHID_RECVDlg::CHID_RECVDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CHID_RECVDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CHID_RECVDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CHID_RECVDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CHID_RECVDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CHID_RECVDlg, CDialog)
	//{{AFX_MSG_MAP(CHID_RECVDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHID_RECVDlg message handlers

BOOL CHID_RECVDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	CenterWindow(GetDesktopWindow());	// center to the hpc screen

	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

//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 OnGetString();
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_BUTTON_GETSTRING:	
			OnGetString();
			break;
		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,_T("启动接收数据线程失败!"),_T("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,_T("启动接收数据线程失败!"),_T("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=0x413c;              //  0x5131     0x413c;    //厂商ID
	USB_PID=0x2003;              //  0x2007     0x2003;    //设备ID
	GUID hidGuid;
	SP_DEVICE_INTERFACE_DATA devInfoData;
	if(hidHandle!=INVALID_HANDLE_VALUE)
	{
		 sprintf(tem,"设备已连接!");
		 SetWindowText(GetDlgItem(MainHwnd,IDC_Status),(unsigned short*)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),(unsigned short*)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,_T("获取HID设备细节信息失败!"),_T("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),(unsigned short*)version);
				m_MaxDataLen=MAX_DATA_LEN;	
			//	MessageBox(NULL,"test","test",MB_YESNO);
				break;
			}
			else//如不是要找的设备,则关闭此设备,再循环查找设备
			{
				CloseHandle(hidHandle);
				deviceNo++;
			}
		}
	}
	//设备未连接,则显示
	if(hidHandle==INVALID_HANDLE_VALUE)
	{
		sprintf(tem,"设备未连接!");
		SetWindowText(GetDlgItem(MainHwnd,IDC_Status),(unsigned short*)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,_T(""));
	HIDOverlapped.hEvent=hEventObject;
	HIDOverlapped.Offset=0;
	HIDOverlapped.OffsetHigh=0;
	if(hidHandle==INVALID_HANDLE_VALUE)
	{
		char   tem[100];
		sprintf(tem,"设备尚未连接!");
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit), (unsigned short*)tem);
		return;
	}
	if(!HidD_GetPreparsedData(hidHandle,&PreparsedData))
	{
	    ULONG  tang=GetLastError();
		char   tem[100];
		sprintf(tem,"Could not get HID preparsed data!");
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit), (unsigned short*)tem);
	}

	NTSTATUS status=HidP_GetCaps(PreparsedData, &Capabilities);
	
	while(!stop)
	{
		ResetEvent(hEventObject);
		ZeroMemory(recvDataBuf,RECV_DATA_LEN);
		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[512]="";
			for(int i=0,j=0;i<64;i++,j+=3)//下位机里定义了38个字符
			{
			sprintf(&tem2[j],"%02X ",(UCHAR)recvDataBuf[i]);
			}
			//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)
				GetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem,180000);
			else
			{
				SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),_T(""));
				flag=FALSE;
			}   
			strcat(tem,tem2);
			SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)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()//清除接收文本框的内容
{
     SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),_T(""));
	 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),(unsigned short*)tem);
	}
	else
	{
		sprintf(tem,"设备未连接!");
		SetWindowText(GetDlgItem(MainHwnd,IDC_Status),(unsigned short*)tem);
	}
	return;
}

void OnGetString()
{
	char tem[256]="";
	char tem2[512]="";
	if(hidHandle==INVALID_HANDLE_VALUE)
	{
		char   tem[100];
		sprintf(tem,"设备尚未连接!");
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem);
		return;
	}

	if(HidD_GetManufacturerString(hidHandle,tem,256))  
	{//生产商
		for(int i=0,j=0;i<61;i++,j+=3)//下位机里定义了38个字符
		{
			sprintf(&tem2[j],"%02X ",(UCHAR)tem[i]);
		}
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem2);
	}
	else
	{
		sprintf(tem2,"函数HidD_GetManufacturerString执行失败");
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem2);
	}
	if(HidD_GetProductString(hidHandle,tem,256))
	{
		printf("产品名称: %s ",tem);
		//SetDlgItemText(MainHwnd,IDC_RecvEdit,tem2);
	}else
	{
		sprintf(tem2,"函数HidD_GetProductString执行失败");
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem2);
	}
	


}


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,_T(""));
	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,"设备尚未连接!");
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem);
		return;
	}
	if(!HidD_GetPreparsedData(hidHandle,&PreparsedData))
	{
	    ULONG  tang=GetLastError();
		char   tem[100];
		sprintf(tem,"Could not get HID preparsed data!");
		SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem);
	}
	status=HidP_GetCaps(PreparsedData, &Capabilities);
	OutputReportLen=Capabilities.OutputReportByteLength;
	char * OutputReport = new char[OutputReportLen];
	ZeroMemory(OutputReport,OutputReportLen);
	//
	OutputReport[0]=0x00;//0x01; 
    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)
				GetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)tem,180000);
			else
			{
				SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)"");
				flag=FALSE;
			}   
			strcat(tem,tem2);
			SetWindowText(GetDlgItem(MainHwnd,IDC_RecvEdit),(unsigned short*)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 + -