Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Keyboard LED control (capslock/numlock/scrolllock lights)


  • Please log in to reply
30 replies to this topic
KoHaN69
  • Members
  • 3 posts
  • Last active: Jun 25 2011 07:51 PM
  • Joined: 29 Jun 2008
Is it possible to disable an LED without making it 'blink' when the CAPSLOCK key is pressed?

I tried
~CapsLock::

  Sleep, 1 ; improve reliability of setting LED state sometimes
  If (GetKeyState("Capslock", "T"))
    KeyboardLED(4,"off")
  
Return
and

~CapsLock::


  If (GetKeyState("Capslock", "T"))
    KeyboardLED(4,"off")
  
Return

But capslock stil blinks when held down
MsgBox,48,, This is not a %MsgBox%!

Broonox
  • Members
  • 2 posts
  • Last active: Oct 08 2010 10:23 AM
  • Joined: 08 Oct 2010
device =\Device\KeyBoardClass2

Works a charm on my USB keyboard. Now, I , am, very, happy..!!. :') *tears of joy*

flashkid
  • Members
  • 115 posts
  • Last active: Apr 12 2013 06:33 PM
  • Joined: 25 Aug 2007
I got a logitech S 510 keyboard. With it comes a usb receiver, which has 3 leds: capslock, numlock and function key.
Is it possible to use the function key led? This led is only triggered when I use the function button on my keyboard (F1-F10 get special hotkeys then), but I never use these function keys. So it would be great to use this led also, so I got 3 usable leds.

Hamlet
  • Members
  • 302 posts
  • Last active: Mar 23 2014 03:37 PM
  • Joined: 22 Jan 2009
I would like to use this nice script in AHK_Lexikos, too.

Please, tell me how to do it ?

I tried MSN DLL pages for couple of hours. But, had nothing.

The explanation is so neat in HELP file for AHK_L. Just pointer something, and that is it. I do not know which one(s) has to change to pointer(s) or not. It is cearly way way over my knowledge and ability.

I am just looking forward someone to show me the way.

THANKS !!!

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
/*

    Keyboard LED control for AutoHotkey_L
        http://www.autohotkey.com/forum/viewtopic.php?p=468000#468000

    KeyboardLED(LEDvalue, "Cmd", Kbd)
        LEDvalue  - ScrollLock=1, NumLock=2, CapsLock=4
        Cmd       - on/off/switch
        Kbd       - index of keyboard (probably 0 or 2)

*/

KeyboardLED(LEDvalue, Cmd, Kbd=0)
{
  SetUnicodeStr(fn,"\Device\KeyBoardClass" Kbd)
  h_device:=NtCreateFile(fn,0+0x00000100+0x00000080+0x00100000,1,1,0x00000040+0x00000020,0)
  
  If Cmd= switch  ;switches every LED according to LEDvalue
   KeyLED:= LEDvalue
  If Cmd= on  ;forces all choosen LED's to ON (LEDvalue= 0 ->LED's according to keystate)
   KeyLED:= LEDvalue | (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
  If Cmd= off  ;forces all choosen LED's to OFF (LEDvalue= 0 ->LED's according to keystate)
    {
    LEDvalue:= LEDvalue ^ 7
    KeyLED:= LEDvalue & (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
    }
  
  success := DllCall( "DeviceIoControl"
              ,  "ptr", h_device
              , "uint", CTL_CODE( 0x0000000b     ; FILE_DEVICE_KEYBOARD
                        , 2
                        , 0             ; METHOD_BUFFERED
                        , 0  )          ; FILE_ANY_ACCESS
              , "int*", KeyLED << 16
              , "uint", 4
              ,  "ptr", 0
              , "uint", 0
              ,  "ptr*", output_actual
              ,  "ptr", 0 )
  
  NtCloseFile(h_device)
  return success
}

CTL_CODE( p_device_type, p_function, p_method, p_access )
{
  Return, ( p_device_type << 16 ) | ( p_access << 14 ) | ( p_function << 2 ) | p_method
}


NtCreateFile(ByRef wfilename,desiredaccess,sharemode,createdist,flags,fattribs)
{
  VarSetCapacity(objattrib,6*A_PtrSize,0)
  VarSetCapacity(io,2*A_PtrSize,0)
  VarSetCapacity(pus,2*A_PtrSize)
  DllCall("ntdll\RtlInitUnicodeString","ptr",&pus,"ptr",&wfilename)
  NumPut(6*A_PtrSize,objattrib,0)
  NumPut(&pus,objattrib,2*A_PtrSize)
  status:=DllCall("ntdll\ZwCreateFile","ptr*",fh,"UInt",desiredaccess,"ptr",&objattrib
                  ,"ptr",&io,"ptr",0,"UInt",fattribs,"UInt",sharemode,"UInt",createdist
                  ,"UInt",flags,"ptr",0,"UInt",0, "UInt")
  return % fh
}

NtCloseFile(handle)
{
  return DllCall("ntdll\ZwClose","ptr",handle)
}


SetUnicodeStr(ByRef out, str_)
{
  VarSetCapacity(out,2*StrPut(str_,"utf-16"))
  StrPut(str_,&out,"utf-16")
}
Changes:
[*:gp18kii8]Now requires AutoHotkey_L.
[*:gp18kii8]Added support for AutoHotkey_L Unicode and 64-bit.
[*:gp18kii8]Added a third parameter - the index of the keyboard device to open. For my USB keyboard, I had to use Kbd = 2.
[*:gp18kii8]Simplified some parts. Compare it to the original script if you're curious.

Hamlet
  • Members
  • 302 posts
  • Last active: Mar 23 2014 03:37 PM
  • Joined: 22 Jan 2009
Thanks !!!!!! Mr. L !!!!!!!

It works well fantastically !!!!!!

Mine are #1 and #2
-for parameter "Kbd", it is really amazing. I really appreciate your careful attention.


I am going to post this nice news to my local AHK community (in S. Korea).

Thanks again !!!!!!

tkmmkt
  • Members
  • 22 posts
  • Last active: Aug 27 2013 08:54 AM
  • Joined: 15 May 2012
In my computer, I have to use Index of keyboard Kdb = 1 to let script worked ;)

For the other, if you want to know the "KeyboardClass" in your system, try to search in registry and you will know in
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\KeyboardClass

I found 02 subkeys in my system. After fail when use Kdb=0, I changed to 1 and this script work well ;)
\Device\KeyboardClass0
\Device\KeyboardClass1

Thanks Lexikos for your script.

eugenes
  • Members
  • 1 posts
  • Last active: Mar 17 2016 12:04 AM
  • Joined: 02 Jun 2013

Had to use Kbd=3 on my desktop (with USB keyboard Gigabyte Osmium; there are overall 5 "KeyboardClass" registry subkeys)

 

Anyway, this script is awesome - have been looking for a long while on how to turn that useless NumLock indicator off while maintaining its function (and disabled Shift with another script - use it as to change keyboard layout instead happy.png).

 

Anyway, thank you very much Lexikos!!!



chaz
  • Members
  • 192 posts
  • Last active: Oct 01 2015 02:42 AM
  • Joined: 26 Mar 2013

Great. I was wondering why the original one didn't work for me. The "switch" command doesn't work for me though. It'll turn the LED on, but won't turn it off. "On" and "Off" work fine.


Find me at the other forum as timeFlies.


XX0
  • Members
  • 32 posts
  • Last active: Dec 12 2014 01:05 PM
  • Joined: 17 Jul 2010

Noticed your remark while I grabbed the AHK_L compatible version. I think you have the wrong expectations for the switch parameter. With switch parameter sets the LED state of all three LED's exactly as you define, on and off. Whereas on/off only sets the state of the LED's you tell it to, leaving the current state of the others as it is. So the switch parameter does not toggle the current state.



vadim1sh
  • Members
  • 1 posts
  • Last active: Sep 18 2013 09:04 PM
  • Joined: 17 Sep 2013

Hi

Should be some corrections for win7?

I checked all "KeyboardClass" (I have 0,1 and 2), tried off and on. Don't work at all :(



freakingprime
  • Members
  • 1 posts
  • Last active: Jan 11 2014 03:42 AM
  • Joined: 07 Jan 2014

Hi.

 

My laptop has some addition led on the keyboard like in wifi toggle button, touchpad lock button, fn lock button. How can I control these led?



Adyanth
  • Members
  • 4 posts
  • Last active: Apr 08 2014 10:20 AM
  • Joined: 14 May 2013

This script allows you to control which capslock/numlock/scrolllock LED indicators are lit up, to produce effects such as flashing and cycling without altering the actual state of those keys (i.e. doesn't interfere with typing).

The script consists of 2 sections: 1) Some examples near the top. 2) The necessary functions.

The code originated here: Using Keyboard LEDs for spectrum.

Credit goes to Shimanov for the original code, Peter for syntax improvements and JGR for the code to get the handle of the keyboard device directly.
 

; Keyboard LED control (capslock/numlock/scrolllock lights)
;   http://www.autohotkey.com/forum/viewtopic.php?t=10532

; USAGE: KeyboardLED(LEDvalue,"Cmd")  ; LEDvalue: ScrollLock=1, NumLock=2, CapsLock=4 ; Cmd = on/off/switch


Loop, 3 ; flash all LEDs
  {
  KeyboardLED(7,"on")
  Sleep, 500
  KeyboardLED(7,"off")
  Sleep, 500
  }
 
Loop, 3 ; flash ScrollLock LED
  {
  KeyboardLED(7,"off")
  KeyboardLED(4,"switch")
  Sleep, 500
  KeyboardLED(7,"off")
  Sleep, 500
  }

Loop, 3 ; cycle all LEDs left to right
  {
  KeyboardLED(7,"off")
  Sleep, 250
  KeyboardLED(2,"switch")
  Sleep, 250
  KeyboardLED(4,"switch")
  Sleep, 250
  KeyboardLED(1,"switch")
  Sleep, 250
  }

Loop, 3 ; progress bar in LEDs
  {
  KeyboardLED(7,"off")
  Sleep, 500
  KeyboardLED(2,"switch")
  Sleep, 500
  KeyboardLED(6,"switch")
  Sleep, 500
  KeyboardLED(7,"switch")
  Sleep, 500
  }

Loop, 3 ; Knight Rider KITT cycling all LEDs ;-)
  {
  KeyboardLED(2,"switch")
  Sleep, 500
  KeyboardLED(4,"switch")
  Sleep, 500
  KeyboardLED(1,"switch")
  Sleep, 500
  KeyboardLED(4,"switch")
  Sleep, 500
  }

KeyboardLED(0,"off")  ; all LED('s) according to keystate (Command = on or off) 
Return



KeyboardLED(LEDvalue, Cmd)  ; LEDvalue: ScrollLock=1, NumLock=2, CapsLock=4 ; Cmd = on/off/switch
{
  Static h_device
  If ! h_device ; initialise
    {
    device =\Device\KeyBoardClass0
    SetUnicodeStr(fn,device) 
    h_device:=NtCreateFile(fn,0+0x00000100+0x00000080+0x00100000,1,1,0x00000040+0x00000020,0)
    }

  VarSetCapacity( output_actual, 4, 0 )
  input_size = 4
  VarSetCapacity( input, input_size, 0 )

  If Cmd= switch  ;switches every LED according to LEDvalue
   KeyLED:= LEDvalue
  If Cmd= on  ;forces all choosen LED's to ON (LEDvalue= 0 ->LED's according to keystate)
   KeyLED:= LEDvalue | (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
  If Cmd= off  ;forces all choosen LED's to OFF (LEDvalue= 0 ->LED's according to keystate)
    {
    LEDvalue:= LEDvalue ^ 7
    KeyLED:= LEDvalue & (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
    }
  ; EncodeInteger( KeyLED, 1, &input, 2 ) ;input bit pattern (KeyLED): bit 0 = scrolllock ;bit 1 = numlock ;bit 2 = capslock
  input := Chr(1) Chr(1) Chr(KeyLED)
  input := Chr(1)
  input=
  success := DllCall( "DeviceIoControl"
              , "uint", h_device
              , "uint", CTL_CODE( 0x0000000b     ; FILE_DEVICE_KEYBOARD
                        , 2
                        , 0             ; METHOD_BUFFERED
                        , 0  )          ; FILE_ANY_ACCESS
              , "uint", &input
              , "uint", input_size
              , "uint", 0
              , "uint", 0
              , "uint", &output_actual
              , "uint", 0 )
}

CTL_CODE( p_device_type, p_function, p_method, p_access )
{
  Return, ( p_device_type << 16 ) | ( p_access << 14 ) | ( p_function << 2 ) | p_method
}


NtCreateFile(ByRef wfilename,desiredaccess,sharemode,createdist,flags,fattribs)
{ 
  VarSetCapacity(fh,4,0) 
  VarSetCapacity(objattrib,24,0) 
  VarSetCapacity(io,8,0) 
  VarSetCapacity(pus,8) 
  uslen:=DllCall("lstrlenW","str",wfilename)*2 
  InsertInteger(uslen,pus,0,2) 
  InsertInteger(uslen,pus,2,2) 
  InsertInteger(&wfilename,pus,4) 
  InsertInteger(24,objattrib,0) 
  InsertInteger(&pus,objattrib,8) 
  status:=DllCall("ntdll\ZwCreateFile","str",fh,"UInt",desiredaccess,"str",objattrib,"str",io,"UInt",0,"UInt",fattribs
                  ,"UInt",sharemode,"UInt",createdist,"UInt",flags,"UInt",0,"UInt",0, "UInt") 
  return % ExtractInteger(fh) 
} 


SetUnicodeStr(ByRef out, str_)
{ 
  VarSetCapacity(st1, 8, 0) 
  InsertInteger(0x530025, st1) 
  VarSetCapacity(out, (StrLen(str_)+1)*2, 0) 
  DllCall("wsprintfW", "str", out, "str", st1, "str", str_, "Cdecl UInt") 
} 


ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4) 
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset. 
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned. 
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int). 
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process 
; (since pSource might contain valid data beyond its first binary zero). 
{ 
  Loop %pSize%  ; Build the integer by adding up its bytes. 
    result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1) 
  if (!pIsSigned OR pSize > 4 OR result < 0x80000000) 
    return result  ; Signed vs. unsigned doesn't matter in these cases. 
  ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart: 
  return -(0xFFFFFFFF - result + 1) 
} 


InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) 
; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest, 
; only pSize number of bytes starting at pOffset are altered in it. 
{ 
  Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data. 
    DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF) 
}

I Used the available scripts to make a script that uses caps lock and scroll lock keys as read and write for removable media such as pendrives as my flash drive doesnt have the light

#SingleInstance, Force
#Persistent
Process, Priority,, High
CoordMode, Tooltip
KeyboardLED(5, "off")
DriveGet, HDD_List, List, Removable
Drives := StrLen(HDD_List)
 
Loop, parse, HDD_List
{
HDD%A_Index%  := A_LoopField
hDrv%A_Index% := DllCall( "CreateFile", Str,"\\.\" . A_LoopField . ":", Uint,0 ,Uint,3, Uint,0, Uint,3, Uint,0, Uint,0), oRC%A_Index% := 0, oWC%A_Index% := 0
}
 
SetTimer, HDD_Monitor, ;500
 
HDD_Monitor:
loop, % Drives
{
  VarSetCapacity(dp%A_Index%, 88)
  DllCall("DeviceIoControl", Uint,hDrv%A_Index%, Uint,0x00070020, Uint,0, Uint,0, Uint, &dp%A_Index%, Uint,88, UintP,nReturn, Uint,0 )
 
  nRC%A_Index% := *(&dp%A_Index%+40) | *(&dp%A_Index%+41) << 8 | *(&dp%A_Index%+42) << 16 | *(&dp%A_Index%+43) << 24
  nWC%A_Index% := *(&dp%A_Index%+44) | *(&dp%A_Index%+45) << 8 | *(&dp%A_Index%+46) << 16 | *(&dp%A_Index%+47) << 24
RC%A_Index% := Round(100-(100*(1/(1+(nRC%A_Index%-oRC%A_Index%))))) , WC%A_Index% := Round(100-(100*(1/(1+(nWC%A_Index%-oWC%A_Index%)))))
If(RC%A_Index% > 0)
KeyboardLED(4,"on")
If(WC%A_Index% > 0)
KeyboardLED(1,"on")
If(RC%A_Index% = 0)
KeyboardLED(4,"off")
If(WC%A_Index% = 0)
KeyboardLED(1,"off")
oRC%A_Index% := nRC%A_Index% ,  oWC%A_Index% := nWC%A_Index%
}
Return
 
 
KeyboardLED(LEDvalue, Cmd)  ; LEDvalue: ScrollLock=1, NumLock=2, CapsLock=4 ; Cmd = on/off/switch
{
  Static h_device
  If ! h_device ; initialise
    {
    device =\Device\KeyBoardClass0
    SetUnicodeStr(fn,device) 
    h_device:=NtCreateFile(fn,0+0x00000100+0x00000080+0x00100000,1,1,0x00000040+0x00000020,0)
    }
 
  VarSetCapacity( output_actual, 4, 0 )
  input_size = 4
  VarSetCapacity( input, input_size, 0 )
 
  If Cmd= switch  ;switches every LED according to LEDvalue
   KeyLED:= LEDvalue
  If Cmd= on  ;forces all choosen LED's to ON (LEDvalue= 0 ->LED's according to keystate)
   KeyLED:= LEDvalue | (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
  If Cmd= off  ;forces all choosen LED's to OFF (LEDvalue= 0 ->LED's according to keystate)
    {
    LEDvalue:= LEDvalue ^ 7
    KeyLED:= LEDvalue & (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
    }
  ; EncodeInteger( KeyLED, 1, &input, 2 ) ;input bit pattern (KeyLED): bit 0 = scrolllock ;bit 1 = numlock ;bit 2 = capslock
  input := Chr(1) Chr(1) Chr(KeyLED)
  input := Chr(1)
  input=
  success := DllCall( "DeviceIoControl"
              , "uint", h_device
              , "uint", CTL_CODE( 0x0000000b     ; FILE_DEVICE_KEYBOARD
                        , 2
                        , 0             ; METHOD_BUFFERED
                        , 0  )          ; FILE_ANY_ACCESS
              , "uint", &input
              , "uint", input_size
              , "uint", 0
              , "uint", 0
              , "uint", &output_actual
              , "uint", 0 )
}
 
CTL_CODE( p_device_type, p_function, p_method, p_access )
{
  Return, ( p_device_type << 16 ) | ( p_access << 14 ) | ( p_function << 2 ) | p_method
}
 
 
NtCreateFile(ByRef wfilename,desiredaccess,sharemode,createdist,flags,fattribs)
{ 
  VarSetCapacity(fh,4,0) 
  VarSetCapacity(objattrib,24,0) 
  VarSetCapacity(io,8,0) 
  VarSetCapacity(pus,8) 
  uslen:=DllCall("lstrlenW","str",wfilename)*2 
  InsertInteger(uslen,pus,0,2) 
  InsertInteger(uslen,pus,2,2) 
  InsertInteger(&wfilename,pus,4) 
  InsertInteger(24,objattrib,0) 
  InsertInteger(&pus,objattrib,8) 
  status:=DllCall("ntdll\ZwCreateFile","str",fh,"UInt",desiredaccess,"str",objattrib,"str",io,"UInt",0,"UInt",fattribs
                  ,"UInt",sharemode,"UInt",createdist,"UInt",flags,"UInt",0,"UInt",0, "UInt") 
  return % ExtractInteger(fh) 
} 
 
 
SetUnicodeStr(ByRef out, str_)
{ 
  VarSetCapacity(st1, 8, 0) 
  InsertInteger(0x530025, st1) 
  VarSetCapacity(out, (StrLen(str_)+1)*2, 0) 
  DllCall("wsprintfW", "str", out, "str", st1, "str", str_, "Cdecl UInt") 
} 
 
 
ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4) 
{ 
  Loop %pSize%  ; Build the integer by adding up its bytes. 
    result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1) 
  if (!pIsSigned OR pSize > 4 OR result < 0x80000000) 
    return result  ; Signed vs. unsigned doesn't matter in these cases. 
  ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart: 
  return -(0xFFFFFFFF - result + 1) 
} 
 
 
InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) 
; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest, 
; only pSize number of bytes starting at pOffset are altered in it. 
{ 
  Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data. 
    DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF) 
}
 
 
 
OnExit:
KeyboardLED(0, "off")
ExitApp


My1
  • Members
  • 10 posts
  • Last active: Sep 14 2015 10:48 PM
  • Joined: 19 Jul 2014

I found this script (the one above from Lexikos) but there is the problem, that somehow it reports the line

SetCapacity(out,2*StrPut(str_,"utf-16"))

with a nonexistent script...

according to the help I have Version 1.0.48.05

do I need to include something???

I'd love to reroute my scrollLock to Caps, since I dont use caps and have no scrollLock button and light...

 

also when trying the script on the 1st page, most of the time my laptop caps only flashes once and then goes off shortly after.

That's my script, st least for this point:

SetCapsLockState, AlwaysOff

CapsLock::
if (getkeystate("Scrolllock","T"))
{
SetScrollLockState, AlwaysOff
KeyboardLED(4, "off")
}
else
{
SetScrollLockState, AlwaysOn
KeyboardLED(4, "on")
}
KeyWait CapsLock
return


NotReallyWorking
  • Members
  • 1 posts
  • Last active: Nov 03 2014 05:59 PM
  • Joined: 15 Oct 2014

So I recently purchased a CM Devastator keyboard, which has a LED backlight.

 

The catch is, that the backlight is toggled with the ScrollLock key.  So you have to have ScrollLock "On" in order to have the backlight.

 

But as a heavy-Excel user, that just won't fly.

 

So I tried writing a script using the library provided in this thread.  However, the KeyboardLED command just doesn't seem to do anything, no matter what KeyboardClass I change it to.  

~ScrollLock::

If (GetKeyState("Scrolllock", "T"))
	KeyboardLED(1, on, kbd=0)
		Else
	KeyboardLED(1, off, kbd=0)
Return

/*

    Keyboard LED control for AutoHotkey_L
        http://www.autohotkey.com/forum/viewtopic.php?p=468000#468000

    KeyboardLED(LEDvalue, "Cmd", Kbd)
        LEDvalue  - ScrollLock=1, NumLock=2, CapsLock=4
        Cmd       - on/off/switch
        Kbd       - index of keyboard (probably 0 or 2)

*/

KeyboardLED(LEDvalue, Cmd, Kbd)
{
  SetUnicodeStr(fn,"\Device\KeyBoardClass" Kbd)
  h_device:=NtCreateFile(fn,0+0x00000100+0x00000080+0x00100000,1,1,0x00000040+0x00000020,0)
  
  If Cmd= switch  ;switches every LED according to LEDvalue
   KeyLED:= LEDvalue
  If Cmd= on  ;forces all choosen LED's to ON (LEDvalue= 0 ->LED's according to keystate)
   KeyLED:= LEDvalue | (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
  If Cmd= off  ;forces all choosen LED's to OFF (LEDvalue= 0 ->LED's according to keystate)
    {
    LEDvalue:= LEDvalue ^ 7
    KeyLED:= LEDvalue & (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T"))
    }
  
  success := DllCall( "DeviceIoControl"
              ,  "ptr", h_device
              , "uint", CTL_CODE( 0x0000000b     ; FILE_DEVICE_KEYBOARD
                        , 2
                        , 0             ; METHOD_BUFFERED
                        , 0  )          ; FILE_ANY_ACCESS
              , "int*", KeyLED << 16
              , "uint", 4
              ,  "ptr", 0
              , "uint", 0
              ,  "ptr*", output_actual
              ,  "ptr", 0 )
  
  NtCloseFile(h_device)
  return success
}

CTL_CODE( p_device_type, p_function, p_method, p_access )
{
  Return, ( p_device_type << 16 ) | ( p_access << 14 ) | ( p_function << 2 ) | p_method
}


NtCreateFile(ByRef wfilename,desiredaccess,sharemode,createdist,flags,fattribs)
{
  VarSetCapacity(objattrib,6*A_PtrSize,0)
  VarSetCapacity(io,2*A_PtrSize,0)
  VarSetCapacity(pus,2*A_PtrSize)
  DllCall("ntdll\RtlInitUnicodeString","ptr",&pus,"ptr",&wfilename)
  NumPut(6*A_PtrSize,objattrib,0)
  NumPut(&pus,objattrib,2*A_PtrSize)
  status:=DllCall("ntdll\ZwCreateFile","ptr*",fh,"UInt",desiredaccess,"ptr",&objattrib
                  ,"ptr",&io,"ptr",0,"UInt",fattribs,"UInt",sharemode,"UInt",createdist
                  ,"UInt",flags,"ptr",0,"UInt",0, "UInt")
  return % fh
}

NtCloseFile(handle)
{
  return DllCall("ntdll\ZwClose","ptr",handle)
}


SetUnicodeStr(ByRef out, str_)
{
  VarSetCapacity(out,2*StrPut(str_,"utf-16"))
  StrPut(str_,&out,"utf-16")
}

Aside from the first handful of lines, the rest is copied from this thread.  What am I doing wrong?

 

I'm using Windows 7 x64 and Autohotkey_L.