(Windows HID API) HidD_GetPreparsedData() 由于句柄不正确导致 WM_INPUT 消息处理程序失败?
(Windows HID API) HidD_GetPreparsedData() failing in WM_INPUT message handler due to incorrect handle?
我正在尝试将 Apple Magic Trackpad 2(最终是任何 Windows Precision Touchpad)的自定义处理写入 Windows 桌面应用程序。我正在使用 this project as a guide, as it accomplishes similar goals. I am at the point where I have registered the HID touchpad, and am able to receive WM_INPUT messages, which I am handling in the code below. Note, I did have to download open-source drivers 以使触摸板正常工作并触发 WM_INPUT 消息。
afx_msg void CSimulatorWnd::OnRawInput( UINT nInputCode, HRAWINPUT hRawInput )
{
/*----------------------------------------------------------
Local variables
----------------------------------------------------------*/
HIDP_CAPS hid_capabilities;
UINT data_size = 0;
PHIDP_PREPARSED_DATA preparsed_data = NULL; // allocated by HidD_GetPreparsedData
PRAWINPUT raw_data_buffer = NULL;
RAWINPUTDEVICELIST * connected_devices = NULL;
// add vars that need to be de-allocated here
#define free_and_return() free( raw_data_buffer ); \
if( preparsed_data ){ HidD_FreePreparsedData( preparsed_data ); } \
return;
// get the required raw data size (returns 0 if successful)
if( GetRawInputData( hRawInput, RID_INPUT, NULL, &data_size, sizeof( RAWINPUTHEADER ) ) != 0
|| data_size == 0 )
{
free_and_return();
}
// allocate space in the input data buffer
raw_data_buffer = (RAWINPUT *)malloc( data_size );
// get the raw data (returns the required buffer size from above if successful)
if( GetRawInputData( hRawInput, RID_INPUT, raw_data_buffer, &data_size, sizeof( RAWINPUTHEADER ) ) != data_size )
{
free_and_return();
}
// only handle registered HIDs
if( raw_data_buffer->header.dwType != RIM_TYPEHID )
{
free_and_return();
}
// get pre-parsed HID data. need this structure
if( !HidD_GetPreparsedData( raw_data_buffer->header.hDevice, &preparsed_data ) )
{
// NOTE: raw_data_buffer->header.hDevice = 0x000000004ddd0ce9,
// returning a ERROR_INVALID_HANDLE for some reason.
//
// Below is the information for the HID I registered.
// The handle is correct. The printout below was from
// enumerating over available devices from GetRawInputDeviceList()
// and the output from GetRawInputDeviceInfo()
//
// *********** HID INFO ***********
// HNDL: 000000004DDD0CE9
// Product ID: 613
// Vendor ID: 35088
// Version Number: 1
// Usage Page: 0X0000000D
// Usage: 0X00000005
// ********************************
DWORD error = GetLastError();
free_and_return();
}
// get multi-touch HID capabilities and data
// https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/supporting-usages-in-multitouch-digitizer-drivers
HidP_GetCaps( preparsed_data, &hid_capabilities );
// free dynamically allocated memory
free_and_return();
} /* CSimulatorWnd::OnRawInput() */
现在,我正处于尝试使用 hidpi.h API 调用获取原始 x、y、联系人等数据的阶段。为了访问其中的任何一个,我需要 HidD_GetPreparsedData() 输出的预解析数据。不幸的是,该函数失败了,并返回一个错误代码,指出提供的句柄(来自原始数据)是错误的。
我错过了什么吗?正如我评论的那样,我传递的句柄看起来正确,与我注册的设备匹配。
我修好了!我不确定为什么我不能使用 HidD_GetPreparsedData(),但是使用 RIDI_PREPARSEDDATA 参数通过 GetRawInputDeviceInfo() 获取数据,效果很好。
RAWINPUTHEADER.hDevice
句柄不适用于 HidD_GetPreparsedData()
API。此句柄只能与 GetRawInputDeviceInfo()
一起使用(如您所见)。
要使用 HidD_GetPreparsedData()
和其他 HIDClass support routines,您需要:
- 通过
::GetRawInputDeviceInfo(raw_data_buffer->header.hDevice, RIDI_DEVICENAME, ..)
调用获取 HID 设备文件名。
- 通过
::CreateFile(device_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, nullptr, nullptr)
调用打开设备文件以获取真正的 HID device_handle
。
- 现在您可以使用
HidD_GetPreparsedData()
.
- 您还可以在该句柄上使用
WriteFile
API 将输出报告发送到 HID 集合。 Details are here and here.
我正在尝试将 Apple Magic Trackpad 2(最终是任何 Windows Precision Touchpad)的自定义处理写入 Windows 桌面应用程序。我正在使用 this project as a guide, as it accomplishes similar goals. I am at the point where I have registered the HID touchpad, and am able to receive WM_INPUT messages, which I am handling in the code below. Note, I did have to download open-source drivers 以使触摸板正常工作并触发 WM_INPUT 消息。
afx_msg void CSimulatorWnd::OnRawInput( UINT nInputCode, HRAWINPUT hRawInput )
{
/*----------------------------------------------------------
Local variables
----------------------------------------------------------*/
HIDP_CAPS hid_capabilities;
UINT data_size = 0;
PHIDP_PREPARSED_DATA preparsed_data = NULL; // allocated by HidD_GetPreparsedData
PRAWINPUT raw_data_buffer = NULL;
RAWINPUTDEVICELIST * connected_devices = NULL;
// add vars that need to be de-allocated here
#define free_and_return() free( raw_data_buffer ); \
if( preparsed_data ){ HidD_FreePreparsedData( preparsed_data ); } \
return;
// get the required raw data size (returns 0 if successful)
if( GetRawInputData( hRawInput, RID_INPUT, NULL, &data_size, sizeof( RAWINPUTHEADER ) ) != 0
|| data_size == 0 )
{
free_and_return();
}
// allocate space in the input data buffer
raw_data_buffer = (RAWINPUT *)malloc( data_size );
// get the raw data (returns the required buffer size from above if successful)
if( GetRawInputData( hRawInput, RID_INPUT, raw_data_buffer, &data_size, sizeof( RAWINPUTHEADER ) ) != data_size )
{
free_and_return();
}
// only handle registered HIDs
if( raw_data_buffer->header.dwType != RIM_TYPEHID )
{
free_and_return();
}
// get pre-parsed HID data. need this structure
if( !HidD_GetPreparsedData( raw_data_buffer->header.hDevice, &preparsed_data ) )
{
// NOTE: raw_data_buffer->header.hDevice = 0x000000004ddd0ce9,
// returning a ERROR_INVALID_HANDLE for some reason.
//
// Below is the information for the HID I registered.
// The handle is correct. The printout below was from
// enumerating over available devices from GetRawInputDeviceList()
// and the output from GetRawInputDeviceInfo()
//
// *********** HID INFO ***********
// HNDL: 000000004DDD0CE9
// Product ID: 613
// Vendor ID: 35088
// Version Number: 1
// Usage Page: 0X0000000D
// Usage: 0X00000005
// ********************************
DWORD error = GetLastError();
free_and_return();
}
// get multi-touch HID capabilities and data
// https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/supporting-usages-in-multitouch-digitizer-drivers
HidP_GetCaps( preparsed_data, &hid_capabilities );
// free dynamically allocated memory
free_and_return();
} /* CSimulatorWnd::OnRawInput() */
现在,我正处于尝试使用 hidpi.h API 调用获取原始 x、y、联系人等数据的阶段。为了访问其中的任何一个,我需要 HidD_GetPreparsedData() 输出的预解析数据。不幸的是,该函数失败了,并返回一个错误代码,指出提供的句柄(来自原始数据)是错误的。
我错过了什么吗?正如我评论的那样,我传递的句柄看起来正确,与我注册的设备匹配。
我修好了!我不确定为什么我不能使用 HidD_GetPreparsedData(),但是使用 RIDI_PREPARSEDDATA 参数通过 GetRawInputDeviceInfo() 获取数据,效果很好。
RAWINPUTHEADER.hDevice
句柄不适用于 HidD_GetPreparsedData()
API。此句柄只能与 GetRawInputDeviceInfo()
一起使用(如您所见)。
要使用 HidD_GetPreparsedData()
和其他 HIDClass support routines,您需要:
- 通过
::GetRawInputDeviceInfo(raw_data_buffer->header.hDevice, RIDI_DEVICENAME, ..)
调用获取 HID 设备文件名。 - 通过
::CreateFile(device_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, nullptr, nullptr)
调用打开设备文件以获取真正的 HIDdevice_handle
。 - 现在您可以使用
HidD_GetPreparsedData()
. - 您还可以在该句柄上使用
WriteFile
API 将输出报告发送到 HID 集合。 Details are here and here.