6

I'm trying to set the keyboard LEDs of a USB keyboard. I already tried / know the following:

  1. To set PS/2 keyboard LEDs you can use the CreateFile("\\.\Keybd", GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); DeviceIoControl(hKeybd, IOCTL_KEYBOARD_SET_INDICATORS...

  2. To set the LEDs of a truly HID compliant keyboard you can use DirectInput, SendDeviceData with the usage page 8.

  3. You can use SendInput / keybd_event. But this will also changes the state. So when you change CAPS LOCK with this method while the user is typing, he/she will get upper and lower case letters :-)

When I investigated method 2 with two keyboards, the SendDeviceData function always returns E_NOTIMPL. It seems a lot of USB keyboard manufacturers rely on the build-in HID driver. In this case the HID driver reports that keyboard as a PC enhanced keyboard ans says it's an "emulation". But the Windows HID emulation doesn't support SendDeviceData.

So I suspect there must be another way to set the keyboards LEDs. Windows must be talking to the USB keyboard to set the LEDs :-)

How can I change the keyboard LEDs without changing the keyboard state?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
martin
  • 61
  • 1
  • 3
  • 1
    May I ask, why you want to do that? – Daniel Hilgarth Mar 21 '11 at 08:29
  • "Windows must be talking to the USB keyboard to set the LEDs". Not sure about that, it can also be the keyboard that sets its LEDs by itself, in this case there would be no way to set it via OS – CharlesB Mar 21 '11 at 08:55
  • @Daniel presumably to blink the LED lights on email, tweet, etc, http://freshmeat.net/projects/ixbiff/ – Steve-o Mar 21 '11 at 09:23
  • 2
    As a user, I would hate for my keyboard LEDs not to reflect the actual keyboard state (whether typing will generate uppercase or not). – Ben Voigt Mar 21 '11 at 14:42
  • @martin The user already has a means to set the LEDs. – David Heffernan Mar 21 '11 at 14:44
  • @Charles: Windows can change the state of the Num Lock LED when you logon as a user who, for example has turned Num Lock off, whereas the login screen has it turned on. Therefore I believe there must be a way for Windows to set the LEDs – martin Apr 01 '11 at 13:24
  • @Daniel: I want to indicate network usage during fullscreen mode. – martin Apr 01 '11 at 13:24
  • @martin: That's your case #3, it changes the LED and the Caps Lock state, which you said you don't want. – Ben Voigt Apr 01 '11 at 18:08
  • FYI http://www.rohitab.com/discuss/topic/32092-toggle-led-lights/ – Polluks Aug 17 '23 at 11:50

1 Answers1

2

Use the HID Descriptor Tool to view the HID Report Descriptors for each keyboard. The keyboard needs to implement usage page 8 ("LEDs"). Otherwise, control of those indicators may not be available through the USB interface or it may be done in a non-standard way.

Alternatively, you could try setting the special key states with keybd_event and maybe Windows will automagically toggle the LED for you.

Judge Maygarden
  • 26,961
  • 9
  • 82
  • 99
  • I already tried that. But when the USB keyboard is not a true HID compliant keyboard, but a "normal" USB keyboard Microsofts HID *emulation* is used. This emulation doesn't support usage page lookup by GetObjectInfo(&didoi, DIMAKEUSAGEDWORD(0x08,0x03), DIPH_BYUSAGE) nor does it support SendDeviceData. MS's SendDeviceData is hard-coded to return error E_NOTIMPL. – martin Apr 01 '11 at 13:20
  • @martin A mouse and keyboard can comply with the minimal "boot" report. In that case, you would not have access to the LED indicators without some other hack of which I am not aware. – Judge Maygarden Apr 01 '11 at 13:30
  • keybd_event worked well for me. It has the advantage to be hardware-independent (worked with both PS/2 and USB keyboards). – Giuseppe Guerrini Apr 24 '14 at 12:09