在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例桌面应用界面/GUI → Windows读 USB口

Windows读 USB口

桌面应用界面/GUI

下载此实例
  • 开发语言:C/C++
  • 实例大小:0.23M
  • 下载次数:75
  • 浏览次数:1095
  • 发布时间:2015-05-09
  • 实例类别:桌面应用界面/GUI
  • 发 布 人:3266456341
  • 文件格式:.rar
  • 所需积分:2
 相关标签: windows

实例介绍

【实例简介】
【实例截图】

【核心代码】

// 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.

//Free any resources used by previous API calls and still allocated.

//Setting ApplicationActive FALSE signals the ReadReport thread to close.
ApplicationActive=FALSE;
//Wait for the ReadReport thread to close.
WaitForSingleObject(ThreadHandle, INFINITE);

//Close open handles.
CloseHandle(DeviceHandle);
DisplayLastError("CloseHandle(DeviceHandle)");
CloseHandle(ReadHandle);
DisplayLastError("CloseHandle(ReadHandle)");
CloseHandle(ThreadHandle);
DisplayLastError("CloseHandle(ThreadHandle)");

CDialog::OnClose();
}

bool CUsbhidiocDlg::FindTheHID()
{
//Use a series of API calls to find a HID with a matching Vendor and Product ID.

HIDD_ATTRIBUTES Attributes;
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
SP_DEVICE_INTERFACE_DATA devInfoData;
bool LastDevice = FALSE;
int MemberIndex = 0;
bool MyDeviceDetected = FALSE; 
LONG Result;


//These are the vendor and product IDs to look for.
//Uses Lakeview Research's Vendor ID.
const unsigned int VendorID = 0x0d8c;
const unsigned int ProductID = 0x000e;

Length = 0;
detailData = NULL;
DeviceHandle=NULL;

/*
API function: HidD_GetHidGuid
Get the GUID for all system HIDs.
Returns: the GUID in HidGuid.
*/

HidD_GetHidGuid(&HidGuid);

/*
API function: SetupDiGetClassDevs
Returns: a handle to a device information set for all installed devices.
Requires: the GUID returned by GetHidGuid.
*/

hDevInfo=SetupDiGetClassDevs \
(&HidGuid, \
NULL, \
NULL, \
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

devInfoData.cbSize = sizeof(devInfoData);

//Step through the available devices looking for the one we want. 
//Quit on detecting the desired device or checking all available devices without success.
MemberIndex = 0;
LastDevice = FALSE;

do
{
MyDeviceDetected=FALSE;

/*
API function: SetupDiEnumDeviceInterfaces
On return, MyDeviceInterfaceData contains the handle to a
SP_DEVICE_INTERFACE_DATA structure for a detected device.
Requires:
The DeviceInfoSet returned in SetupDiGetClassDevs.
The HidGuid returned in GetHidGuid.
An index to specify a device.
*/

Result=SetupDiEnumDeviceInterfaces \
(hDevInfo, \
0, \
&HidGuid, \
MemberIndex, \
&devInfoData);

if (Result != 0)
{
//A device has been detected, so get more information about it.

/*
API function: SetupDiGetDeviceInterfaceDetail
Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
containing information about a device.
To retrieve the information, call this function twice.
The first time returns the size of the structure in Length.
The second time returns a pointer to the data in DeviceInfoSet.
Requires:
A DeviceInfoSet returned by SetupDiGetClassDevs
The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.

The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
This application doesn't retrieve or use the structure.
If retrieving the structure, set 
MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
and pass the structure's address.
*/

//Get the Length value.
//The call will return with a "buffer too small" error which can be ignored.
Result = SetupDiGetDeviceInterfaceDetail \
(hDevInfo, \
&devInfoData, \
NULL, \
0, \
&Length, \
NULL);

//Allocate memory for the hDevInfo structure, using the returned Length.
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);

//Set cbSize in the detailData structure.
detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

//Call the function again, this time passing it the returned buffer size.
Result = SetupDiGetDeviceInterfaceDetail \
(hDevInfo, \
&devInfoData, \
detailData, \
Length, \
&Required, \
NULL);

//Open a handle to the device.

/*
API function: CreateFile
Returns: a handle that enables reading and writing to the device.
Requires:
The DevicePath in the detailData structure
returned by SetupDiGetDeviceInterfaceDetail.
*/

DeviceHandle=CreateFile \
(detailData->DevicePath, \
GENERIC_READ|GENERIC_WRITE, \
FILE_SHARE_READ|FILE_SHARE_WRITE, \
NULL, \
OPEN_EXISTING, \
0, \
NULL);

DisplayLastError("CreateFile: ");

/*
API function: HidD_GetAttributes
Requests information from the device.
Requires: the handle returned by CreateFile.
Returns: a HIDD_ATTRIBUTES structure containing
the Vendor ID, Product ID, and Product Version Number.
Use this information to decide if the detected device is
the one we're looking for.
*/

//Set the Size to the number of bytes in the structure.
Attributes.Size = sizeof(Attributes);

Result = HidD_GetAttributes \
(DeviceHandle, \
&Attributes);

DisplayLastError("HidD_GetAttributes: ");

//Is it the desired device?
MyDeviceDetected = FALSE;


if (Attributes.VendorID == VendorID)
{
if (Attributes.ProductID == ProductID)
{
//Both the Product and Vendor IDs match.
MyDeviceDetected = TRUE;
DisplayData("Device detected");
//Get the device's capablities.
GetDeviceCapabilities();
//Use this handle for writing reports.
WriteHandle=DeviceHandle;
//ReadFile is a blocking call, 
//so get another handle for another thread for reading reports.
ReadHandle=CreateFile \
(detailData->DevicePath, \
GENERIC_READ|GENERIC_WRITE, \
FILE_SHARE_READ|FILE_SHARE_WRITE, \
NULL, \
OPEN_EXISTING, \
0, \
NULL);
DisplayLastError("CreateFile for Read Handle: ");

/*
Create a thread for reading reports from the device.
ReadFile is a blocking call, so it's called in a separate program thread.
This keeps the main program thread from hanging while waiting for a
report from the device.
In CreateThread, StaticIO_Thread is a static member that accepts
the "this" pointer and casts it to a pointer to the ReadReport routine, 
which does the ReadFile.
*/

ThreadHandle = CreateThread \
(NULL, \
0, \
(LPTHREAD_START_ROUTINE)StaticIO_Thread, \
this, \
0, \
&ThreadID);

if (ThreadHandle == NULL)
CloseHandle(ThreadHandle);

DisplayLastError("CreateThread: ");

} //if (Attributes.ProductID == ProductID)
else
//The Product ID doesn't match.
CloseHandle(DeviceHandle);
} //if (Attributes.VendorID == VendorID)
else
//The Vendor ID doesn't match.
CloseHandle(DeviceHandle);

//Free the memory used by the detailData structure (no longer needed).
free(detailData);
}  //if (Result != 0)
else
//SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
LastDevice=TRUE;

//If we haven't found the device yet, and haven't tried every available device,
//try the next one.
MemberIndex = MemberIndex 1;

} //do
while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));

if (MyDeviceDetected == FALSE)
DisplayData("Device not detected");

SetupDiDestroyDeviceInfoList(hDevInfo);
DisplayLastError("SetupDiDestroyDeviceInfoList");

return MyDeviceDetected;
}

void CUsbhidiocDlg::GetDeviceCapabilities()
{
//Get the Capabilities structure for the device.
PHIDP_PREPARSED_DATA PreparsedData;

/*
API function: HidD_GetPreparsedData
Returns: a pointer to a buffer containing the information about the device's capabilities.
Requires: A handle returned by CreateFile.
There's no need to access the buffer directly,
but HidP_GetCaps and other API functions require a pointer to the buffer.
*/

HidD_GetPreparsedData \
(DeviceHandle, \
&PreparsedData);
DisplayLastError("HidD_GetPreparsedData: ");

/*
API function: HidP_GetCaps
Learn the device's capabilities.
For standard devices such as joysticks, you can find out the specific
capabilities of the device.
For a custom device, the software will probably know what the device is capable of,
and the call only verifies the information.
Requires: the pointer to the buffer returned by HidD_GetPreparsedData.
Returns: a Capabilities structure containing the information.
*/

HidP_GetCaps \
(PreparsedData, \
&Capabilities);
DisplayLastError("HidP_GetCaps: ");

//Display the capabilities
CString ValueToDisplay;
ValueToDisplay.Format("%s%X", "Usage Page: ", Capabilities.UsagePage);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Input Report Byte Length: ", Capabilities.InputReportByteLength);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Output Report Byte Length: ", Capabilities.OutputReportByteLength);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Feature Report Byte Length: ", Capabilities.FeatureReportByteLength);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Link Collection Nodes: ", Capabilities.NumberLinkCollectionNodes);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Input Button Caps: ", Capabilities.NumberInputButtonCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of InputValue Caps: ", Capabilities.NumberInputValueCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of InputData Indices: ", Capabilities.NumberInputDataIndices);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Output Button Caps: ", Capabilities.NumberOutputButtonCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Output Value Caps: ", Capabilities.NumberOutputValueCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Output Data Indices: ", Capabilities.NumberOutputDataIndices);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Feature Button Caps: ", Capabilities.NumberFeatureButtonCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Feature Value Caps: ", Capabilities.NumberFeatureValueCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Feature Data Indices: ", Capabilities.NumberFeatureDataIndices);
DisplayData(ValueToDisplay);

//No need for PreparsedData any more, so free the memory it's using.
HidD_FreePreparsedData(PreparsedData);
DisplayLastError("HidD_FreePreparsedData: ") ;
}

void CUsbhidiocDlg::ReadAndWriteToDevice()
{
//If we haven't done so already, find the device and learn its capabilities.
//Then send a report and request a report.
//The test device firmware (usbhidio) adds 1 to each byte received in an OUT report
//and sends the results back in the next IN report.

//Clear the List Box (optional).
//m_ResultsList.ResetContent();

//Don't attempt anything if a previous transfer hasn't completed.
{
DisplayData("***HID Test Report***");
DisplayCurrentTime();

//If the device hasn't been detected already, look for it.
if (DeviceDetected==FALSE)
DeviceDetected=FindTheHID();

if (DeviceDetected==TRUE)
{

//Write a report to the device.
WriteReport();

//Get the latest report read from the device and display it.
DisplayInputReport();

} // (EndIf: if DeviceDetected == True)
}

}

DWORD CUsbhidiocDlg::StaticIO_Thread(LPVOID Param)
{
//Used in creating a thread for ReadFiles.
//Accepts the "this" pointer and casts it to a pointer to ReadReport.
if (Param != NULL)
return ((CUsbhidiocDlg*)Param)->ReadReport();
else
return -1;
}

DWORD WINAPI CUsbhidiocDlg::ReadReport()
{
CString ByteToDisplay = "";
ULONG InputReportLength = 0;
CString MessageToDisplay = "";
ULONG Result;

//Read a report from the device.

InputReportLength=Capabilities.InputReportByteLength;

do
{
/*
ReadFile
Returns:
A report in InputReport.
The number of bytes actually read in BytesRead.
Requires: 
A device handle returned by CreateFile.
The report length returned by HidP_GetCaps in Capabilities.InputReportByteLength.
*/
ActualBytesRead = BytesRead;
Result = ReadFile \
(ReadHandle, \
InputReport, \
Capabilities.InputReportByteLength, \
&BytesRead, \
NULL);


ActualBytesRead = BytesRead;

if (Result == 0)
{
//The ReadFile failed, so close the handle, display a message,
//and set DeviceDetected to FALSE so the next attempt will look for the device.
CloseHandle(ReadHandle);
DisplayData("Can't read from device");
DeviceDetected = FALSE;
}
DisplayCurrentTime();
DisplayInputReport();
}
//Exit the loop if the device is no longer detected or the user has clicked the close button.
while ((DeviceDetected == TRUE) && (ApplicationActive == TRUE));

    return 0;
}
#include "math.h"
static int i = 0;
void CUsbhidiocDlg::WriteReport()
{
//Send a report to the device.

DWORD BytesWritten = 0;
INT Index0 =0,Index1 =0,Index2 =0,Index3 =0,Index4 =0;
CHAR OutputReport[5];
ULONG Result;
CString strBytesWritten = "";

//The first byte is the report number.
OutputReport[0]=0;
OutputReport[1]=0;
OutputReport[2]=0x0f;
OutputReport[3]=0x0f;

//Get the values from the combo boxes.
OutputReport[0]=m_cboByteToSend0.GetCurSel();
OutputReport[1]=m_cboByteToSend1.GetCurSel();
OutputReport[2]=m_cboByteToSend2.GetCurSel();
OutputReport[3]=m_cboByteToSend3.GetCurSel();
OutputReport[4]=m_cboByteToSend4.GetCurSel();



//Get the bytes to send from the combo boxes.

//If Autoincrement is checked, increment the selection.
if (m_cbutAutoIncrement0.GetCheck()>0)
{
Index0=m_cboByteToSend0.GetCurSel();
Index0=Index0 1;
m_cboByteToSend0.SetCurSel(Index0);

}

if (m_cbutAutoIncrement1.GetCheck()>0)
{
Index1=m_cboByteToSend1.GetCurSel();
Index1=Index1 1;
m_cboByteToSend1.SetCurSel(Index1);

}

if (m_cbutAutoIncrement2.GetCheck()>0)
{
Index2=m_cboByteToSend2.GetCurSel();
Index2=Index2 1;
m_cboByteToSend2.SetCurSel(Index2);

}

if (m_cbutAutoIncrement3.GetCheck()>0)
{
Index3=m_cboByteToSend3.GetCurSel();
Index3=Index3 1;
m_cboByteToSend3.SetCurSel(Index3);

}

if (m_cbutAutoIncrement4.GetCheck()>0)
{
Index4=m_cboByteToSend4.GetCurSel();
Index4=Index4 1;
m_cboByteToSend4.SetCurSel(Index4);

}



//OutputReport[3]=pow(2,i);
i ;
if (i==1)
{
OutputReport[1]=0x30;
}

if (i==2)
{
OutputReport[1]=0x00;
i=0;
}

/*
WriteFile
Sends a report to the device.
Returns: success or failure.
Requires:
The device handle returned by CreateFile.
The Output Report length returned by HidP_GetCaps,
A report to send.
*/

Result = WriteFile \
(DeviceHandle, \
OutputReport, \
Capabilities.OutputReportByteLength, \
&BytesWritten, \
NULL);

if (Result == 0)
{
//The WriteFile failed, so close the handle, display a message,
//and set DeviceDetected to FALSE so the next attempt will look for the device.
CloseHandle(DeviceHandle);
DisplayData("Can't write to device");
DeviceDetected = FALSE;
}

//Display the result of the API call and the report bytes.
DisplayLastError("WriteFile: ");
strBytesWritten.Format("%s%d", "Bytes Written: ", BytesWritten); 
DisplayData(strBytesWritten);
}

/*
Display-related routines
*/

// 二进制倍
union Abb
{
char data;
struct wei 
{
UINT a1:1;
UINT a2:1;
UINT a3:1;
UINT a4:1;
UINT a5:1;
UINT a6:1;
UINT a7:1;
UINT a8:1;
}X;
};

bool rec;
void CUsbhidiocDlg::DisplayInputReport()
{
USHORT ByteNumber;
CString MessageToDisplay = "";
CHAR ReceivedByte;
//Display the number of bytes read.
MessageToDisplay.Format("%s%d", "Number of Bytes Read: ", ActualBytesRead); 
DisplayData(MessageToDisplay);

//Display the received data in the log and the Bytes Received List boxes.
//Start at the top of the List Box.
//m_BytesReceived.ResetContent();
/*
if (InputReport[2]==0x51)
{
rec=!rec;
}
//Step through the received bytes and display each.
//for (ByteNumber=0; ByteNumber < Capabilities.InputReportByteLength; ByteNumber )
if (rec && (InputReport[2]!=0x11) && (InputReport[1]!=0x00))*/
// {
// if (InputReport[2]==0x51)
// {
// m_BytesReceived.ResetContent();
// }

// CString strRead;
// for (ByteNumber=0; ByteNumber < Capabilities.InputReportByteLength; ByteNumber )
// {
// ReceivedByte = InputReport[ByteNumber];
// //Display it.
// CString strByteRead;
// //Convert the value to a 2-character Cstring.
// strByteRead.Format("%02X", ReceivedByte);
// strByteRead = strByteRead.Right(2); 
// strRead =strByteRead " ";
// }

{
CString strRead, strByteRead; // 字节字符串
Abb unByte1, unByte2;
for (ByteNumber=0; ByteNumber < Capabilities.InputReportByteLength; ByteNumber )
{
ReceivedByte = InputReport[ByteNumber];
//Display it.
CString strByteRead;
//Convert the value to a 2-character Cstring.
strByteRead.Format("%02X", ReceivedByte);
strByteRead = strByteRead.Right(2);
strRead =strByteRead " ";

if ( !(ByteNumber>0 && ByteNumber<3) )
continue;
// 得到第二个字节和第三个字节 
ByteNumber == 1 ? unByte1.data = InputReport[ByteNumber] : unByte2.data = InputReport[ByteNumber];
}
strByteRead.Format("  %d%d%d%d %d%d%d%d ", // 字节顺序
unByte1.X.a7, unByte1.X.a8, 
unByte2.X.a1, unByte2.X.a2, unByte2.X.a3,
unByte2.X.a5, unByte2.X.a6, unByte2.X.a7
);

strRead = strByteRead; // 连接二个串

//Display the value in the Bytes Received List Box.

CTime curTime = CTime::GetCurrentTime();
CString CurrentTime = curTime.Format( "%H:%M:%S" );

m_BytesReceived.InsertString(-1, strRead "  " CurrentTime);
m_BytesReceived.SetCurSel(m_BytesReceived.GetCount()-1); 
/*
//Get a byte.
ByteNumber=1;
{
CTime curTime = CTime::GetCurrentTime();
CString CurrentTime = curTime.Format( "%H:%M:%S" );
ReceivedByte = InputReport[ByteNumber];
//Display it.
CString strByteRead;
//Convert the value to a 2-character Cstring.
strByteRead.Format("%02X", ReceivedByte);
strByteRead = strByteRead.Right(2); 
//Display the value in the Bytes Received List Box.
m_BytesReceived.InsertString(-1, strByteRead "  " CurrentTime);
//DisplayReceivedData(ReceivedByte);
}
ByteNumber=2;

{
ReceivedByte = InputReport[ByteNumber];
//Display it.
DisplayReceivedData(ReceivedByte);
}
*/

}
}

void CUsbhidiocDlg::DisplayCurrentTime()
{
//Get the current time and date and display them in the log List Box.
CTime curTime = CTime::GetCurrentTime();
CString CurrentTime = curTime.Format( "%H:%M:%S, %B %d, %Y" );
DisplayData(CurrentTime);
}

void CUsbhidiocDlg::DisplayData(CString cstrDataToDisplay)
{
//Display data in the log List Box
USHORT Index;
Index=m_ResultsList.InsertString(-1, (LPCTSTR)cstrDataToDisplay);
ScrollToBottomOfListBox(Index);
}

void CUsbhidiocDlg::DisplayLastError(CString Operation)
{
//Display a message and the last error in the log List Box. 
LPVOID lpMsgBuf;
USHORT Index = 0;
CString strLastError = "";
FormatMessage( 
FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM | 
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL 
);

//Display the last error.
strLastError = Operation (LPCTSTR)lpMsgBuf; 
//Trim CR/LF from the error message.
strLastError.TrimRight(); 
Index = m_ResultsList.InsertString(-1, strLastError);
ScrollToBottomOfListBox(Index);
LocalFree(lpMsgBuf); 
}

void CUsbhidiocDlg::DisplayReceivedData(char ReceivedByte)
{
//Display data received from the device.
CString strByteRead;
//Convert the value to a 2-character Cstring.
strByteRead.Format("%02X", ReceivedByte);
strByteRead = strByteRead.Right(2); 
//Display the value in the Bytes Received List Box.
m_BytesReceived.InsertString(-1, strByteRead);
//Display the value in the log List Box (optional).
//MessageToDisplay.Format("%s%s", "Byte 0: ", strByteRead); 
//DisplayData(MessageToDisplay);
}

void CUsbhidiocDlg::OnChangeResults() 
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.

// TODO: Add your control notification handler code here
}

void CUsbhidiocDlg::ScrollToBottomOfListBox(USHORT Index)
{
/* 
Scroll to the bottom of the list box. 
To do so, add a line and set it as the current selection,
possibly scrolling the window.
Then deselect the line, 
leaving the list box scrolled to the bottom with nothing selected.
*/

m_ResultsList.SetCurSel( Index );
m_ResultsList.SetCurSel( -1 );
}

/*
Misc. routines.
*/

void CUsbhidiocDlg::OnTimer(UINT nIDEvent) 
{
//The timer event.
//Read and Write one pair of reports.
ReadAndWriteToDevice();

CDialog::OnTimer(nIDEvent);
}

void CUsbhidiocDlg::OnOK() 
{
CDialog::OnOK();
}





void CUsbhidiocDlg::OnDblclkList2() 
{
// TODO: Add your control notification handler code here
m_ResultsList.ResetContent();
}

标签: windows

实例下载地址

Windows读 USB口

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 luyop0163 发表于: 2020-01-05 00:34 07
什么鬼东西,,根本没有USB相关的

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有1条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警