Win32 确定何时连接/断开键盘

2022-01-13 00:00:00 keyboard c winapi c++ device

我正在尝试确定我的键盘何时连接或断开.我尝试了以下策略:

I am trying to determine when my keyboard is connected or disconnected. I have tried the following strategies:

注册设备通知

按照 MSDN 在 如何确定在 DirectInput 中断开的键盘.当我尝试这个时,我在窗口回调中得到 DB_DEVNODES_CHANGED 事件,它没有提供其他信息(只是 一些未知 设备已更改连接状态).我尝试了各种 GUID 进行注册:4D36E96B-E325-11CE-BFC1-08002BE10318(一些网站说这是键盘的类 guid)和从 IDirectInput8::EnumDevices(DI8DEVCLASS_KEYBOARD) 检索的 guidInstance, ..., DIEDFL_ATTACHEDONLY).但我仍然只得到 DB_DEVNODES_CHANGED 事件.

Using RegisterDeviceNotifaction as explained on MSDN was suggested in how to determine keyboard disconnected in DirectInput. When I tried this I get DB_DEVNODES_CHANGED event in the window callback which provides no other information (just some unknown device has changed connection state). I tried various GUIDs for the registration: 4D36E96B-E325-11CE-BFC1-08002BE10318 (several websites said this is the class guid for keyboards) and the guidInstance retrieved from IDirectInput8::EnumDevices(DI8DEVCLASS_KEYBOARD, ..., DIEDFL_ATTACHEDONLY). But I still only get the DB_DEVNODES_CHANGED event.

IDirectInput8::EnumDevices

IDirectInput8::EnumDevices(DI8DEVCLASS_KEYBOARD, ..., DIEDFL_ATTACHEDONLY) 的每次调用都应仅枚举连接的设备.然而,当我断开我的键盘时,它仍然被 EnumDevices 枚举.当我对我的游戏控制器(类型为 DI8DEVCLASS_GAMECTRL)执行相同操作时,控制器仅在连接时被枚举,允许我确定其连接状态.

Each call to IDirectInput8::EnumDevices(DI8DEVCLASS_KEYBOARD, ..., DIEDFL_ATTACHEDONLY) should only enumerate the devices that are attached. However, when I disconnect my keyboard, it still gets enumerated by EnumDevices. When I do the same for my game controller (with the type DI8DEVCLASS_GAMECTRL) the controller is only enumerated when it is attached, allowing me to determine its connection state.

其他功能

我试过了:

  1. IDirectInput8::GetDeviceStatus
  2. IDirectInputDevice8::GetCapabilities
  3. IDirectInputDevice8::GetDeviceInfo
  4. IDirectInputDevice8::GetDeviceState
  5. IDirectInputDevice8::Poll

所有功能都成功,并且无法了解键盘是否已连接.

All functions succeed and provide no insight into if the keyboard is connected.

我还查看了 MSDN 的 键盘部分,无济于事.

I have also looked through MSDN's keyboard section, to no avail.

问题

  1. 任何成功完成此操作的人都可以确认我采取了正确的方法吗?
  2. 我是否忽略了其他函数或 API?
  3. 有什么网站可以举个例子(我用谷歌搜索不成功)?
  4. 为什么 EnumDevices 在我的控制器上正常工作,但在我的键盘上却不行?以及如何使它适用于我的键盘?
  1. Can anyone who has done this successfully confirm I'm taking the right approach?
  2. Is there another function or API I am overlooking?
  3. Any websites that give an example (I've googled unsuccessfully)?
  4. Why does EnumDevices work correctly for my controller but not my keyboard? And how do I make it work for my keyboard?

推荐答案

你有没有考虑过 GetRawInputDeviceList()GetRawInputDeviceInfo(),对 pData 使用 RID_DEVICE_INFO 并检查它的 dwType?

Have you considered GetRawInputDeviceList() and GetRawInputDeviceInfo(), using RID_DEVICE_INFO for pData and checking it's dwType?

这将为您提供初始状态,然后如果您的 wndProc 处理 WM_INPUT_DEVICE_CHANGE,您可以使用参数来检测添加/删除,并且可以将 lParam 直接发送到 GetRawInputDeviceInfo().

That will get you the initial state, then if your wndProc handles WM_INPUT_DEVICE_CHANGE you can use the params to detect add/remove, and the lParam can be sent straigth to GetRawInputDeviceInfo().

根据评论:WM_INPUT_DEVICE_CHANGE 仅适用于已调用 RegisterRawInputDevices() 并专门要求此通知的应用.

Per comments: The WM_INPUT_DEVICE_CHANGE will only arrive for apps that have called RegisterRawInputDevices() and specifically asked for this notification.

相关文章