RunHolt
RunHolt

Reputation: 1982

Win32 determining when keyboard is connected/disconnected

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

RegisterDeviceNotification

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

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.

Other Functions

I have tried:

  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.

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

Questions

  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?

Upvotes: 5

Views: 4510

Answers (1)

Joe
Joe

Reputation: 2986

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

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().

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

Upvotes: 3

Related Questions