Win32 determining when keyboard is connected/disconnected
Asked Answered
U

1

5

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?
Ullund answered 29/3, 2012 at 18:9 Comment(1)
Please use less NOISE in your formatting. It makes your question harder to read with all of the huge fonts in bold cluttering it up. I've quieted things down to make it understandable (and actually numbered your list items so they make sense). The easier your question is to read, the better your chances are of getting an answer (and usually more quickly, as well). :)Substituent
S
3

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.

Smokejumper answered 29/3, 2012 at 18:24 Comment(5)
This is better. When I have a keyboard plugged in the device list contains 2 keyboard devices. When I remove the keyboard it lowers to one. So I'm tracking down if I can get more info from GetRawInputDeviceInfo. I don't get the WM_INPUT_DEVICE_CHANGE event in my event loop. Is there something special I need to do in order to receive that event? I'm running a console app and a window-less event loop.Ullund
This page (link) for WM_INPUT_DEVICE_CHANGE says "Desktop Apps Only" which implies it wouldn't be sent to a console application.Cornet
@uesp: That is a Metro vs Normal app note, a console app can have normal windows if it wants.Wozniak
My bad. Check the docs for RegisterRawInputDevices for how to register to receive the WM_ message. I did not remember that they don't show up by default. Sounds like you've managed to cobble together some kind of message loop/wndproc for the console app, so hopefully it's just the registration that's preventing the message.Smokejumper
I can get the connect/disconnect. However, my PC is showing 2 keyboards. When I unplug my keyboard, it says I still have a keyboard. I don't have a way of associating the keyboard being plugged in with the keyboard from DirectInput (which I am capturing keystrokes). It wouldn't be so bad if GetRawInputDeviceList returned only one keyboard. I suppose I will assume one keyboard, make an initial count, and when the count decrements assume my one keyboard was unplugged.Ullund

© 2022 - 2024 — McMap. All rights reserved.