目前我使用以下 autohotkey 脚本通过 CapsLock 按钮更改键盘布局。
SetCapsLockState, AlwaysOff
+CapsLock::CapsLock
#SingleInstance force
CapsLock::Send, {ALTDOWN}{SHIFTDOWN}{SHIFTUP}{CTRLUP}{ALTUP}
; in wind
; Send, #{SPACE}
return
我希望当布局为波斯语时 CapsLock LED 亮起,当布局为英语时关闭。可以吗?我确实希望在 CapsLock 保持关闭时切换 LED。
答案1
有一个图书馆叫键盘 LED 控制可用于切换键盘 LED,与其相应的功能无关。使用此方法并执行类似以下操作:
#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
以下是上述链接中的库,供参考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")
}
注意:您可能必须更改 Kbd 的默认值。Kbd=2
为了在 Windows 8 中工作, 我必须将其更改为。使用此值直到看到响应(0-5 应该是有效的)。
答案2
我认为使用 CapsLock LED 不是一个好主意,这里有一个带有 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")
}
}