使用CapsLock重新映射,使用发光二极管,无需大写

时间:2016-01-05 09:31:52

标签: autohotkey

我想重新映射一些密钥(LeftRightUpDownHomeEnd)而{{1按下了。有两个不可或缺的条件。第一个:CapsLock的灯应该打开和关闭。第二个:压缩的字母不应该是 ALL CAPS 全部大写。

例如,我可以使用下面的代码。问题是,所有按下的字母都将被大写。 CapsLock变为aA变为b,依此类推。这很糟糕。

B

我也可以删除tilda(见第一行):

~CapsLock::
Suspend, Toggle
Return

Left::
SendInput {Up}
Return

但问题是,键盘上的灯不会被切换。它会一直关闭。这也很糟糕。

这样做的方法是什么?

1 个答案:

答案 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多行。