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

📄 usbhidiocdlg.cpp

📁 VC下的USB编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// usbhidiocDlg.cpp : implementation file
/*
Project: usbhidioc.cpp
Version: 1.2
Date: 8/17/00
by Jan Axelson (jan@lvr.com)

Purpose: demonstrates USB communications with a HID-class device

Description: 
	Finds an attached HID-class device that matches specific vendor & product IDs.
	Retrieves the device's capabilities.
	Sends two bytes to the device using Input reports.
	Receives two bytes from the device using Output reports. 
	A list box displays a log of activity.
	A Bytes Received list box displays the most recent received report bytes.
	Combo boxes enable the user to select what bytes to send.
	An autoincrement check box causes the application to increment the bytes sent
with each report.
	Clicking the Once button causes the application to exchange one set of reports.
	Clicking the Continuous button causes the application to exchange reports periodically
(every 5 seconds).
	
This application was created with Visual C++ 6's AppWizard as a dialog-based application.

Companion firmware and other sample code is available from www.lvr.com.

I owe a big thank you to the many generous contributors on Usenet and the excellent archive at 
www.deja.com/usenet for helping me with Visual C++ in this project. Other sources I used were 
www.natsemi.com's example HID application and John Hyde's terminal program at 
www.usb-by-example.com.

Send comments, questions, bug reports, etc. to jan@lvr.com.

Fixes: 
1. In the call to SetupDiEnumDeviceInterfaces, the fourth parameter is now MemberIndex instead of 0.
(Thanks to Bob Nathan).
2. free(detailData) was in the wrong place. It's now at the very end of the 
if (Result !=0)
statement. (Thanks to Adam Gresswell.)
3. Added the ApplicationActive flag and code to terminate the ReadReport thread in CUsbhidiocDlg::OnClose.
(Thanks to Sang-Gon Park.)
*/

#include "stdafx.h"
#include "usbhidioc.h"
#include "usbhidiocDlg.h"

#include <wtypes.h>
#include <initguid.h>

#define MAX_LOADSTRING 256

extern "C" {
#include "hidsdi.h"
#include <setupapi.h>
}

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

//function prototypes
bool	FindTheHID();
DWORD WINAPI ReadReport();
void DisplayCurrentTime();
void DisplayData(CString cstrDataToDisplay);
void DisplayInputReport();
void DisplayLastError(CString Operation);
void DisplayReceivedData(char ReceivedByte);
void GetDeviceCapabilities();
void ReadAndWriteToDevice();
void ScrollToBottomOfListBox(USHORT Index);
void WriteReport();

static DWORD StaticIO_Thread(LPVOID);

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUsbhidiocDlg dialog

CUsbhidiocDlg::CUsbhidiocDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CUsbhidiocDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CUsbhidiocDlg)
	m_AutoIncrement = FALSE;
	m_ResultsString = _T("");
	m_strBytesReceived = _T("");
	m_strByteToSend0 = _T("");
	m_strByteToSend1 = _T("");
	m_strByteToSend2 = _T("");
	m_strByteToSend3 = _T("");
	m_strByteToSend4 = _T("");
	m_AutoIncrement0 = FALSE;
	m_AutoIncrement1 = FALSE;
	m_AutoIncrement2 = FALSE;
	m_AutoIncrement3 = FALSE;
	m_AutoIncrement4 = FALSE;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}


//Application global variables 
	DWORD		ActualBytesRead;
	bool		ApplicationActive;
	DWORD		BytesRead;
	HIDP_CAPS	Capabilities;
	bool		DeviceDetected;
	HANDLE		DeviceHandle;
	HANDLE		hDevInfo;
	GUID		HidGuid;
	char		InputReport[5];
	ULONG		Length;
	HANDLE		ReadHandle;
	ULONG		Required;
	HANDLE		ThreadHandle;
	DWORD		ThreadID;
	HANDLE		WriteHandle;

void CUsbhidiocDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CUsbhidiocDlg)
	DDX_Control(pDX, IDC_AutoIncrement4, m_cbutAutoIncrement4);
	DDX_Control(pDX, IDC_AutoIncrement3, m_cbutAutoIncrement3);
	DDX_Control(pDX, IDC_AutoIncrement2, m_cbutAutoIncrement2);
	DDX_Control(pDX, IDC_AutoIncrement1, m_cbutAutoIncrement1);
	DDX_Control(pDX, IDC_AutoIncrement0, m_cbutAutoIncrement0);
	DDX_Control(pDX, IDC_cboByteToSend4, m_cboByteToSend4);
	DDX_Control(pDX, IDC_cboByteToSend3, m_cboByteToSend3);
	DDX_Control(pDX, IDC_cboByteToSend2, m_cboByteToSend2);
	DDX_Control(pDX, IDC_Continuous, m_Continuous);
	DDX_Control(pDX, IDC_cboByteToSend1, m_cboByteToSend1);
	DDX_Control(pDX, IDC_cboByteToSend0, m_cboByteToSend0);
	DDX_Control(pDX, IDC_lstBytesReceived, m_BytesReceived);
	DDX_Control(pDX, IDC_LIST2, m_ResultsList);
	DDX_Control(pDX, IDC_Once, m_Once);
	DDX_LBString(pDX, IDC_LIST2, m_ResultsString);
	DDX_LBString(pDX, IDC_lstBytesReceived, m_strBytesReceived);
	DDX_CBString(pDX, IDC_cboByteToSend0, m_strByteToSend0);
	DDX_CBString(pDX, IDC_cboByteToSend1, m_strByteToSend1);
	DDX_CBString(pDX, IDC_cboByteToSend2, m_strByteToSend2);
	DDX_CBString(pDX, IDC_cboByteToSend3, m_strByteToSend3);
	DDX_CBString(pDX, IDC_cboByteToSend4, m_strByteToSend4);
	DDX_Check(pDX, IDC_AutoIncrement0, m_AutoIncrement0);
	DDX_Check(pDX, IDC_AutoIncrement1, m_AutoIncrement1);
	DDX_Check(pDX, IDC_AutoIncrement2, m_AutoIncrement2);
	DDX_Check(pDX, IDC_AutoIncrement3, m_AutoIncrement3);
	DDX_Check(pDX, IDC_AutoIncrement4, m_AutoIncrement4);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CUsbhidiocDlg, CDialog)
	//{{AFX_MSG_MAP(CUsbhidiocDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_Once, OnOnce)
	ON_EN_CHANGE(IDC_Results, OnChangeResults)
	ON_BN_CLICKED(IDC_Continuous, OnContinuous)
	ON_WM_TIMER()
	ON_WM_CLOSE()
	ON_LBN_DBLCLK(IDC_LIST2, OnDblclkList2)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUsbhidiocDlg message handlers

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

	//My declares begin here
	int		ByteToSend =0;
	CString	strByteToSend = "";
	CString	strComboBoxText="";
	//End my declares

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 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
	
	/*
	My code begins here.
	Anything that needs to happen when the application starts goes in this routine.
	*/

	//Populate the combo boxes with values from 00 to FF.
	DeviceDetected=FALSE;
	ApplicationActive=TRUE;

	for (ByteToSend=0; ByteToSend < 256; ByteToSend++)
	{
		//Display the value as a 2-digit Hex value.
		strByteToSend.Format("%.2X",ByteToSend);
		//Add the value to the combo boxes.
		m_cboByteToSend0.AddString(strByteToSend);
		m_cboByteToSend1.AddString(strByteToSend);	
		m_cboByteToSend2.AddString(strByteToSend);	
		m_cboByteToSend3.AddString(strByteToSend);	
		m_cboByteToSend4.AddString(strByteToSend);	
	}

	//Select default values for the combo boxes.
	//m_cboByteToSend0.SetCurSel(0);
	//m_cboByteToSend1.SetCurSel(128);
	m_cboByteToSend0.SetCurSel(0);
	m_cboByteToSend1.SetCurSel(0);
	m_cboByteToSend2.SetCurSel(255);
	m_cboByteToSend3.SetCurSel(17);
	m_cboByteToSend4.SetCurSel(0);


	//Check the autoincrement check box.
	//m_cbutAutoIncrement.SetCheck(1);

	//Set the caption for the Continous button.
	m_Continuous.SetWindowText("Continuous");
	//end my code

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CUsbhidiocDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CUsbhidiocDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CUsbhidiocDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

/*
My routines (routines specific to this application) start here.
*/

void CUsbhidiocDlg::OnOnce() 
{
	//Click the Once button to read and write one pair of reports.
	ReadAndWriteToDevice();
}


void CUsbhidiocDlg::OnContinuous() 
{
	//Click the Continuous button to
	//begin or stop requesting and sending periodic reports.
	CString Caption;

	//Find out whether Continuous is currently selected 
	//and take appropriate action.
	m_Continuous.GetWindowText(Caption);
	if (Caption == "Continuous")
	{
		//Enable periodic exchanges of reports.
		//Change the button caption.
		m_Continuous.SetWindowText("Stop Continuous");
		//Start by reading and writing one pair of reports.
		ReadAndWriteToDevice();
		//Enable the timer to cause periodic exchange of reports.
		SetTimer(ID_CLOCK_TIMER, 100, NULL);
	}
	else
	{
		//Stop periodic exchanges of reports.
		//Change the button caption.
		m_Continuous.SetWindowText("Continuous");
		//Disable the timer.
		KillTimer(ID_CLOCK_TIMER);
	}
}

void CUsbhidiocDlg::OnClose() 
{
	//Anything that needs to occur on closing the application goes here.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -