2

Currently I use following autohotkey script to change keyboard layout using the CapsLock button.

SetCapsLockState, AlwaysOff

+CapsLock::CapsLock

#SingleInstance force


CapsLock::Send, {ALTDOWN}{SHIFTDOWN}{SHIFTUP}{CTRLUP}{ALTUP}
; in wind
; Send, #{SPACE}

    return

I want CapsLock LED be turned on when layout is Persian and off when it is Englsih. Is it possible? Indeed I want LED be switched wile CapsLock remains off.

3

There is a library called Keyboard LED Control which can be used to toggle the keyboard leds independent of their corresponding function. Use this method and doing something along the lines of:

#Include led.ahk
global PersionLayout := 0

CapsLock::
    Send, {ALTDOWN}{SHIFTDOWN}{SHIFTUP}{CTRLUP}{ALTUP}
    PersionLayout := !PersionLayout
    If PersionLayout = 1
        KeyboardLED(7, "on")
    Else
        KeyboardLED(7, "off")
Return

Here is the library from the above link for reference led.ahk:

/*

    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")
}

Note: You will likely have to change the default value for Kbd. I had to change mine to Kbd=2 in order to work in Windows 8. Play with this value until you see a response (0-5 should be valid).

  • Thanks. Why did you set LEDvalue = 7 ? As I see CapsLock code is 4. – PHPst Jul 2 '13 at 15:32
  • Should I remove SetCapsLockState, AlwaysOff? – PHPst Jul 2 '13 at 15:36
  • You can keep your top 3 lines. The 7 was for all of the lights on the KB. If you only want the CapsLock LED, 4 should do it. Although, I have seen the numbers switched for certain keyboards, but it will be either 4, 2, or 1. – Elliot DeNolf Jul 2 '13 at 15:39
  • Dear Ellion, When I press CapsLock fast the LED switches but the Keyboard language do not switch, is there any solution? Thanks in advance. – PHPst Aug 27 '13 at 6:24
  • Try SetKeyDelay, 0 at the top of your script. This makes it so the keystrokes to change the layout go faster. Your other option is to find a better way to change layout, preferable programmatically. Then to put that in the script instead of your Send keys. – Elliot DeNolf Aug 27 '13 at 13:05
1

I think that the use CapsLock LED is not a good idea, here's an example with TrayTip:

; ListLines, Off
SetCapsLockState, Off
DllCall("RegisterShellHookWindow", "Ptr", A_ScriptHwnd)
OnMessage(DllCall("RegisterWindowMessage"(A_IsUnicode ? "W":"A")
                                         , "Str", "SHELLHOOK", "UInt")
                                         , "ShellMessage")
OnExit, % "ExitScript"
Global bState:=False

~CapsLock::bState:=!bState

ExitScript:
   DllCall("DeregisterShellHookWindow", "Ptr", A_ScriptHwnd)
   ExitApp

ShellMessage(aParams*)
{
   If aParams.1=4 ; HSHELL_WINDOWACTIVATED
   {
      HKL:=DllCall("GetKeyboardLayout", "UInt"
    , DllCall("GetWindowThreadProcessId", "Ptr", WinActive("A")
                                        , "UInt*", 0
                                        , "UInt")
                                      , "Ptr")
      IfEqual, bState, % False, TrayTip,, % "current is: "(HKL&16 ? "fa":"en")
   }
}

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.