使用 Windows 自带 API 枚举并完成读写的详细步骤,参考下面两篇文章:
https://blog.csdn.net/phenixyf/article/details/72478933
https://blog.csdn.net/phenixyf/article/details/9153195
根据上面文章自己完成的 HID GUI 模板位置如下:
使用同步还是异步方式访问 HID 在下面两个地方确定:
用同步方式打开 HID 设备:
hidHandle = CreateFile(devDetail->DevicePath,
NULL, // 第一次必须用非读写模式打开
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0, // 用同步方式
NULL);
用异步方式打开 HID 设备:
hidHandle = CreateFile(devDetail->DevicePath,
NULL, // 第一次必须用非读写模式打开
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, // 用异步方式 (overlap)
NULL);
用同步方式读写
//写操作
WriteFile(hidHandle, Write_HID_Buf, HIDREPORTNUM, &bytesWritten, NULL);
//读操作
ReadFile(hidHandle, Read_HID_Buf, HIDREPORTNUM, &bytesRead, NULL);
用异步方式读写
//写操作
OVERLAPPED hid_write_overlap; //定义 overlap 对象
WriteFile(hidHandle, Write_HID_Buf, HIDREPORTNUM, &bytesWritten, &hid_write_overlap);
//读操作
OVERLAPPED hid_read_overlap; //定义 overlap 对象
ReadFile(hidHandle, Read_HID_Buf, HIDREPORTNUM, &bytesRead, &hid_read_overlap);
同步方式和异步方式操作过程中的不同:
所以一般情况下都会使用异步方式访问 HID 设备。
异步操作的具体实现
异步方式有两种实现方式:
用线程的方式比较麻烦,如果是在 Windows 系统开发,可以使用 overlap,具体实现如下代码
void ChidTemplateDlg::WriteHIDOutputReport()
{
DWORD bytesWritten = 0;
BOOL result = false;
DWORD res_wait_object;
Write_HID_Buf[0] = REPORTID_DATA;
if (hidHandle != INVALID_HANDLE_VALUE)
{
result = WriteFile(hidHandle, Write_HID_Buf, HIDREPORTNUM, &bytesWritten, &hid_write_overlap);
if (!result) //因为是 overlap 异步操作,所以 WriteFile 后不会马上返回 true,这是正常的。
//判断最终写操作是否成功,是在下面的 switch 中
{
if (GetLastError() == ERROR_IO_PENDING)
{//当错误是ERROR_IO_PENDING,那意味着写文件的操作还在进行中
//等候,直到文件读完
switch ( WaitForSingleObject(hidHandle, HIDREADTIMEOUT) )
{
case WAIT_OBJECT_0:
// MessageBox(_T("HID write successfully"));
break;
case WAIT_TIMEOUT:
MessageBox(_T("HID write fail: timeout"));
CloseHandle(hidHandle); // close hid handle
OpenHIDDevice(1); // re-open hid
break;
default:
MessageBox(_T("HID write fail: in overlap process"));
break;
}
}
else
{
MessageBox(_T("HID write fail: not in overlap process"));
}
}
}
else
MessageBox(_T("write hid fail: hid handle is invaliable"));
}
void ChidTemplateDlg::ReadHIDInputReport()
{
DWORD bytesRead = 0;
BOOL result = false;
DWORD res_wait_object;
if (hidHandle != INVALID_HANDLE_VALUE)
{
result = ReadFile(hidHandle, Read_HID_Buf, HIDREPORTNUM, &bytesRead, &hid_read_overlap);
if (!result) //因为是 overlap 异步操作,所以 ReadFile 后不会马上返回 true,这是正常的。
//判断最终读操作是否成功,是在下面的 switch 中
{
if (GetLastError() == ERROR_IO_PENDING)
{//当错误是ERROR_IO_PENDING,那意味着读文件的操作还在进行中
//等候,直到文件读完
switch (WaitForSingleObject(hidHandle, HIDREADTIMEOUT))
{
case WAIT_OBJECT_0:
// MessageBox(_T("HID write successfully"));
break;
case WAIT_TIMEOUT:
MessageBox(_T("HID read fail: timeout"));
CloseHandle(hidHandle); // close hid handle
OpenHIDDevice(1); // re-open hid
break;
default:
MessageBox(_T("HID read fail: in overlap process"));
break;
}
}
else
{
MessageBox(_T("HID read fail: not in overlap process"));
}
}
}
else
MessageBox(_T("read hid fail: hid handle is invaliable"));
}
关于 overlap 及其使用的具体讲解可参考下面文章:
https://blog.csdn.net/phenixyf/article/details/126854005
https://blog.csdn.net/phenixyf/article/details/126853088
(582条消息) Overlapped_Phenixyf的博客-CSDN博客