How to turn on a keyboard light

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
drkenrich1688
Posts: 12
Joined: 04 Feb 2017, 15:12

How to turn on a keyboard light

19 Nov 2017, 16:43

I'm no way a programmer. I'm thoroughly lost here. But, I love you guys for writing scripts I can use. Thanks a heap!

I'm using a small script with a Diablo 3 that toggles an on/off state using the ` key (lowercase just above the Tab). I've tried changing it to NumLock so it would give a light indicator when it's on and no light when it's off. Keypress worked, but no light came on. Here's the script. Is there a simply way to work a keyboard light like NumLock into it so I can tell when it's on or off? On my keyboard I actually have 3 indicators - NK (number keys), CK (cap keys), and WK (don't know what this one is).

Code: Select all

`::
toggle := !toggle
if (toggle) {
	;loop % keyList.MaxIndex()    ;uncomment these 2 lines if you want the delay to start initially or after key press
		;keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;reset nextinterval to default interval
	settimer,auto,10
} else {
	settimer,auto,off
}
return
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: How to turn on a keyboard light

19 Nov 2017, 17:00

Check out:
https://autohotkey.com/board/topic/9587 ... ntry446105

Edit: or if you don't care about the state of your actual NumLock you can try using ~NumLock:: and it should still toggle the light like normal since the native function will still work.
Guest

Re: How to turn on a keyboard light

22 Nov 2017, 00:27

Amazing script. I don't know how it works, but I'll give it a try. Thank you so much! :dance:
drkenrich1688
Posts: 12
Joined: 04 Feb 2017, 15:12

Re: How to turn on a keyboard light

22 Nov 2017, 23:31

I was jazzed with the suggested script until I tried to get it to work. First I logged into AutoHotKey. Then I went to that page to try to ask how to make it work. It asked me to log in again, but wouldn't accept my previous or a repeat of my login. So. here's my question.

How am I supposed to use it? Do I just copy it into my little script? Where?
Do I input some new line to call the script saved as some identifiable file? What file? What does that line have to say EXACTLY?

Also, it seams a bit much for my use. All I want to do is turn on either the CapsLock or NumLock light and then turn it off when I exit the script.

Please remember, I'm a total dud with programming.
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: How to turn on a keyboard light

23 Nov 2017, 07:57

Here is an example using the code in your first post. The only trick is getting your keyboard index, for me it is 1 but that isn't always the case it seems.

The comment above the function gives a description of each parameter, including what number for each individual light to use (add them for multiple).

Code: Select all

`::
toggle := !toggle
if (toggle) {
	;loop % keyList.MaxIndex()    ;uncomment these 2 lines if you want the delay to start initially or after key press
		;keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;reset nextinterval to default interval
	settimer,auto,10
	KeyboardLED(4, "On", 1) ; On my machine 1 is my active keyboard, your might be 0, or 2...
} else {
	settimer,auto,off
	KeyboardLED(4, "Off", 1) ; On my machine 1 is my active keyboard, your might be 0, or 2...
}
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=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")
}

auto:
; Whatever your auto label does.
return
drkenrich1688
Posts: 12
Joined: 04 Feb 2017, 15:12

Re: How to turn on a keyboard light

24 Nov 2017, 18:09

Okay, My first step was to paste the code into a test script to run in place where I want to use it. When I clicked on run it gave me an error code about duplicate "auto" so I placed a ; in front of a couple of lines to clear that problem. That was near the end just above the F8 reference. Next, I had changed the toggle key from ~ to F12. I did this a day ago and it was working fine. I found that I'd actually added in an additional toggle as F11 thinking I would have two toggles for different processes so I put a ; there, too. Finally I went to the section with KeyboardLED(4, "On", 2) about in the middle and changed the 1 to 0 then 2.

In the game the toggle works for the original purposes, but no lights come on or off. What's my next step?

BTW, thank you for your help.

Code: Select all

settitlematchmode,3 ;this affects IfWinNotActive, 2= partial window match, 3=title must match exactly
keyList := []   ;Declare variables to be used later.
keyList.insert(["2",20500,0]) ;object = "key",interval,nextInterval=0
keyList.insert(["3",90500,0])
keyList.insert(["4",120100,0])
keyList.insert(["r",15100,0])
toggle := false
return ;script stops here and becomes idle, waiting for hotkeys

F12::
toggle := !toggle
if (toggle) {
	;loop % keyList.MaxIndex()    ;uncomment these 2 lines if you want the delay to start initially or after key press
		;keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;reset nextinterval to default interval
	settimer,auto,10
} else {
	settimer,auto,off
}
return

auto:
loop % keyList.MaxIndex() { ;loop through our array of keys
	ifWinNotActive,Diablo III ;if window not active then toggle off
	{
		settimer,auto,off
		toggle := false
		break
	}
	if (a_tickcount > keyList[a_index][3]) { ;if enough time has passed since last press do something
		keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;set next interval
		key := keyList[a_index][1]
		send {%key% down}
		sleep 50
		send {%key% up}
	}
}
return


;   F11::
;   toggle := !toggle
if (toggle) {
	;loop % keyList.MaxIndex()    ;uncomment these 2 lines if you want the delay to start initially or after key press
		;keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;reset nextinterval to default interval
	settimer,auto,10
	KeyboardLED(4, "On", 2) ; On my machine 1 is my active keyboard, your might be 0, or 2...
} else {
	settimer,auto,off
	KeyboardLED(4, "Off", 2) ; On my machine 1 is my active keyboard, your might be 0, or 2...
}
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=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")
}

;  auto:    ; Whatever your auto label does.
return



f8::exitapp ;closes program
f9::reload ;reloads program
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: How to turn on a keyboard light

26 Nov 2017, 15:07

It looks like you commented out the F11 toggle key, and that is where you added the function calls. Your F12 toggle code doesn't include the KeyboardLED calls at all.

Try this, and still experiment with keyboard numbers.

Code: Select all

settitlematchmode,3 ;this affects IfWinNotActive, 2= partial window match, 3=title must match exactly
keyList := []   ;Declare variables to be used later.
keyList.insert(["2",20500,0]) ;object = "key",interval,nextInterval=0
keyList.insert(["3",90500,0])
keyList.insert(["4",120100,0])
keyList.insert(["r",15100,0])
toggle := false
return ;script stops here and becomes idle, waiting for hotkeys


;; -- This is where your code runs on toggle, and you were missing the KeyboardLED calls.
F12::
toggle := !toggle
if (toggle) {
	;loop % keyList.MaxIndex()    ;uncomment these 2 lines if you want the delay to start initially or after key press
		;keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;reset nextinterval to default interval
	settimer,auto,10
	KeyboardLED(4, "On", 2) ; On my machine 1 is my active keyboard, your might be 0, or 2...
} else {
	settimer,auto,off
	KeyboardLED(4, "Off", 2) ; On my machine 1 is my active keyboard, your might be 0, or 2...
}
return

auto:
loop % keyList.MaxIndex() { ;loop through our array of keys
	ifWinNotActive,Diablo III ;if window not active then toggle off
	{
		settimer,auto,off
		toggle := false
		break
	}
	if (a_tickcount > keyList[a_index][3]) { ;if enough time has passed since last press do something
		keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;set next interval
		key := keyList[a_index][1]
		send {%key% down}
		sleep 50
		send {%key% up}
	}
}
return

;; -- This will never be called since it isn't in Autoexecute, and you commented out the hotkey.
;   F11::
;   toggle := !toggle
if (toggle) {
	;loop % keyList.MaxIndex()    ;uncomment these 2 lines if you want the delay to start initially or after key press
		;keyList[a_index][3] := a_tickcount + keyList[a_index][2] ;reset nextinterval to default interval
	settimer,auto,10
	KeyboardLED(4, "On", 2) ; On my machine 1 is my active keyboard, your might be 0, or 2...
} else {
	settimer,auto,off
	KeyboardLED(4, "Off", 2) ; On my machine 1 is my active keyboard, your might be 0, or 2...
}
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=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")
}

f8::exitapp ;closes program
f9::reload ;reloads program
Edit: It almost looked like you wanted to have two separate toggles, one for the light to change (F11) and one without (F12) but then just commented out the hotkey for the lighted one.
drkenrich1688
Posts: 12
Joined: 04 Feb 2017, 15:12

Re: How to turn on a keyboard light

27 Nov 2017, 20:46

Wonderful!! It Works!!

I replaced the code I had with yours and it still didn't seem to work so I went to the line ...KeyboardLED(4, "On", 2)... and made a few changes. First, I really don't know what I'm doing so any changes I make are strictly if I understand something and then make small changes and am ready to restore it.

It says that the final number, 2, is for the keyboard and has to be set to 1, 2, or 0 on a trial basis, so I did that. It didn't seem to make any difference. Also, It says that the first number, 4, represents which key will light (the NumLock light). Then I realized I had my NumLock already on so I turned it off so it wouldn't interfere. Then I changed the 4 to 7 for all the lights and it worked. Only the NumLock and CapsLock came on but that's enough for me. My keyboard is a Teknmotion Nibiru K1 game keyboard and has three keyboard light - NK, CK, and WK. the WK doesn't seem to be connected with anything and I haven't been able to find out what it's for, but I don't care.

Thank you for our help. It will really help me.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: mikeyww, segolore and 332 guests