📄 usbtherm.cpp
字号:
/* extract the capabilities info */
HidP_GetCaps( HidParsedData ,&Capabilities);
/* Free the memory allocated when getting the preparsed data */
HidD_FreePreparsedData(HidParsedData);
/* Create a new event for report capture */
ReportEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
/* fill the HidOverlapped structure so that Windows knows which
event to cause when the device sends an IN report */
HidOverlapped.hEvent = ReportEvent;
HidOverlapped.Offset = 0;
HidOverlapped.OffsetHigh = 0;
/* Use WriteFile to send an output report to the HID device. In this
case we are turning on the READY LED on the target */
outbuffer[0] = 0; /* this is used as the report ID */
outbuffer[1] = 1; /* this flag turns on the LED */
bResult = WriteFile( hDevice,
&outbuffer[0],
Capabilities.OutputReportByteLength,
&numBytesReturned,
(LPOVERLAPPED) &HidOverlapped);
bResult = WaitForSingleObject(ReportEvent, 200);
while(endthread == FALSE)
{
/* get a temperature report from the HID device. Note that
this call to ReadFile only kicks off the reading of the report.
If the input buffer is full then this routine will cause an
event to happen and data will be presented immediately. If not
the event will occur when the HID decide provides a HID report
on the IN endpoint. */
bResult = ReadFile( hDevice, /* handle to device */
&inbuffer[0], /* IN report buffer to fill */
Capabilities.InputReportByteLength, /* input buffer size */
&numBytesReturned, /* returned buffer size */
(LPOVERLAPPED) &HidOverlapped ); /* long pointer to an OVERLAPPED structure */
/* wait for IN report event. Note that if a report does not occur
in the time set by the 'dwMilliseconds' parameter, then this function
returns with a FALSE result and the HID device did not provide a
report. If the function returns TRUE, then a report did occur and the
data is ready to be read from the buffer specified in the ReadFile
function call.*/
bResult = WaitForSingleObject( ReportEvent,
300);
/* if the transaction timed out, then we have to manually cancel
the request */
if(bResult == WAIT_TIMEOUT || bResult == WAIT_ABANDONED)
CancelIo(&hDevice);
/* Process in the input data. Note that the first byte (i.e.
inbuffer[0] is the report ID for the HID report. We can just
ignore this value. The first data byte of interest is
inbuffer[1] */
if(bResult == WAIT_OBJECT_0)
{
/* check if user pressed button for units toggle */
if(inbuffer[1] == 1)
TempDisplayUnits = (TempDisplayUnits == CELCIUS) ? FAHRENHEIT : CELCIUS;
/* check for valid temperature and display it */
temperature = (short)inbuffer[2] + ((short)inbuffer[3] << 8);
if(temperature < 394 && temperature > 217)
{
SendMessage(hTempGraph, PBM_SETPOS, (temperature-218)*57/100, 0);
if(TempDisplayUnits == CELCIUS)
{
sprintf(msgstring,"%d癈", temperature - 273);
SetDlgItemText(hDlg, IDC_TEMPERATURE, msgstring);
}
else
{
sprintf(msgstring,"%d癋", (((temperature - 273)*9)/5) + 32);
SetDlgItemText(hDlg, IDC_TEMPERATURE, msgstring);
}
}
else
{
SendMessage(hTempGraph, PBM_SETPOS, 0, 0);
if(TempDisplayUnits == CELCIUS)
SetDlgItemText(hDlg, IDC_TEMPERATURE, "**癈");
else
SetDlgItemText(hDlg, IDC_TEMPERATURE, "**癋");
}
}
}
/* Use WriteFile to send an output report to the HID device. In this
case we are turning off the READY LED on the target */
outbuffer[0] = 0; /* this is used as the report ID */
outbuffer[1] = 0; /* this flag turns on the LED */
bResult = WriteFile( hDevice,
&outbuffer[0],
Capabilities.OutputReportByteLength,
&numBytesReturned,
(LPOVERLAPPED) &HidOverlapped);
bResult = WaitForSingleObject(ReportEvent, 200);
/* close the HID device handle */
CloseHandle(hDevice);
}
TMThreadActive = FALSE;
}
/**********************************************************
*
* Function: bOpenHidDevice
* Purpose: tries to open a HID device based on VID and PID
* Parameters: vid - HID device's vendor ID
* pid - HID device's product ID
* HidDevHandle - pointer to a handle to the HID device
* Returns: TRUE, if device is found
* FALSE, if device is not found
*
**********************************************************/
BOOL bOpenHidDevice(HANDLE *HidDevHandle, USHORT vid, USHORT pid)
{
static GUID HidGuid; /* HID Globally Unique ID: windows supplies us with this value */
HDEVINFO HidDevInfo; /* handle to structure containing all attached HID Device information */
SP_DEVICE_INTERFACE_DATA devInfoData; /* Information structure for HID devices */
BOOLEAN Result; /* result of getting next device information structure */
DWORD Index; /* index of HidDevInfo array entry */
DWORD DataSize; /* size of the DeviceInterfaceDetail structure */
BOOLEAN GotRequiredSize; /* 1-shot got device info data structure size flag */
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;/* device info data */
DWORD RequiredSize; /* size of device info data structure */
BOOLEAN DIDResult; /* get device info data result */
HIDD_ATTRIBUTES HIDAttrib; /* HID device attributes */
/* initialize variables */
GotRequiredSize = FALSE;
/* 1) Get the HID Globally Unique ID from the OS */
HidD_GetHidGuid(&HidGuid);
/* 2) Get an array of structures containing information about
all attached and enumerated HIDs */
HidDevInfo = SetupDiGetClassDevs( &HidGuid,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
/* 3) Step through the attached device list 1 by 1 and examine
each of the attached devices. When there are no more entries in
the array of structures, the function will return FALSE. */
Index = 0; /* init to first index of array */
devInfoData.cbSize = sizeof(devInfoData); /* set to the size of the structure
that will contain the device info data */
do {
/* Get information about the HID device with the 'Index' array entry */
Result = SetupDiEnumDeviceInterfaces( HidDevInfo,
0,
&HidGuid,
Index,
&devInfoData);
/* If we run into this condition, then there are no more entries
to examine, we might as well return FALSE at point */
if(Result == FALSE)
{
/* free the memory allocated for DetailData */
if(detailData != NULL)
free(detailData);
/* free HID device info list resources */
SetupDiDestroyDeviceInfoList(HidDevInfo);
return FALSE;
}
if(GotRequiredSize == FALSE)
{
/* 3) Get the size of the DEVICE_INTERFACE_DETAIL_DATA
structure. The first call will return an error condition,
but we'll get the size of the strucure */
DIDResult = SetupDiGetDeviceInterfaceDetail( HidDevInfo,
&devInfoData,
NULL,
0,
&DataSize,
NULL);
GotRequiredSize = TRUE;
/* allocate memory for the HidDevInfo structure */
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(DataSize);
/* set the size parameter of the structure */
detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
}
/* 4) Now call the function with the correct size parameter. This
function will return data from one of the array members that
Step #2 pointed to. This way we can start to identify the
attributes of particular HID devices. */
DIDResult = SetupDiGetDeviceInterfaceDetail( HidDevInfo,
&devInfoData,
detailData,
DataSize,
&RequiredSize,
NULL);
/* 5) Open a file handle to the device. Make sure the
attibutes specify overlapped transactions or the IN
transaction may block the input thread. */
*HidDevHandle = CreateFile( detailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
/* 6) Get the Device VID & PID to see if it's the device we want */
if(*HidDevHandle != INVALID_HANDLE_VALUE)
{
HIDAttrib.Size = sizeof(HIDAttrib);
HidD_GetAttributes( *HidDevHandle, &HIDAttrib);
if((HIDAttrib.VendorID == VID) && (HIDAttrib.ProductID == PID))
{
/* free the memory allocated for DetailData */
if(detailData != NULL)
free(detailData);
/* free HID device info list resources */
SetupDiDestroyDeviceInfoList(HidDevInfo);
return TRUE; /* found HID device */
}
/* 7) Close the Device Handle because we didn't find the device
with the correct VID and PID */
CloseHandle(*HidDevHandle);
}
Index++; /* increment the array index to search the next entry */
} while(Result == TRUE);
/* free the memory allocated for DetailData */
if(detailData != NULL)
free(detailData);
/* free HID device info list resources */
SetupDiDestroyDeviceInfoList(HidDevInfo);
return FALSE;
}
/**********************************************************
*
* Function: bHidDeviceNotify
* Purpose: Sets up the HID device notification events. The
* message contains the events
* DBT_DEVICEARRIVAL and DBT_DEVICEREMOVALCOMPLETE. It
* is then up to the application to find out if the
* event is refering to the device it is connected with by
* parsing a structure that the event points to.
* Parameters: hWnd - handle to window that notifications should be
* sent to.
* Returns: TRUE, if device notification is set up
* FALSE, if device notification setup fails
*
**********************************************************/
BOOL bHidDeviceNotify(HWND hWnd, HDEVNOTIFY hDevNotify)
{
GUID HidGuid; /* temporarily stores Windows HID Class GUID */
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; /* un/plug notification filter */
/* Set up device notification (i.e. plug or unplug of HID Devices) */
/* 1) get the HID GUID */
HidD_GetHidGuid(&HidGuid);
/* 2) clear the notification filter */
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter));
/* 3) assign the previously cleared structure with the correct data
so that the application is notified of HID device un/plug events */
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = HidGuid;
/* 4) register device notifications for this application */
hDevNotify = RegisterDeviceNotification( hWnd,
&NotificationFilter,
DEVICE_NOTIFY_WINDOW_HANDLE );
/* 5) notify the calling procedure if the HID device will not be recognized */
if(!hDevNotify)
return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -