我想重新映射一些密钥(Left
,Right
,Up
,Down
,Home
,End
)而{{1按下了。有两个不可或缺的条件。第一个:CapsLock
的灯应该打开和关闭。第二个:压缩的字母不应该是 ALL CAPS 全部大写。
例如,我可以使用下面的代码。问题是,所有按下的字母都将被大写。 CapsLock
变为a
,A
变为b
,依此类推。这很糟糕。
B
我也可以删除tilda(见第一行):
~CapsLock::
Suspend, Toggle
Return
Left::
SendInput {Up}
Return
但问题是,键盘上的灯不会被切换。它会一直关闭。这也很糟糕。
这样做的方法是什么?
答案 0 :(得分:1)
这需要一些DLL调用,是的,它是hacky。令人惊奇的是它甚至可能。 这非常简短:
Kbd := 0 ;if that doesn't work try 2 instead
virtualCapslockState := False
KeyboardLED(4,"off",Kbd)
Capslock::
virtualCapslockState := !virtualCapslockState
If (virtualCapslockState)
KeyboardLED(4,"on",Kbd)
Else
KeyboardLED(4,"off",Kbd)
Return
#If virtualCapslockState
Left::Up
Right::Down
Up::Left
Down::Right
Home::End
End::Home
#If
/*
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 , 2 , 0 , 0 ) , "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")
}
您也可以删除评论。通过用三元运算符替换if语句并将小函数内容直接放到需要的位置,可以节省10多行。