3
votes

I'd like to remap the numeric keypad with Numlock On to behave like the numeric keypad with Numlock Off, including being able to extend the selection with Shift/Ctrl held down.

The problem I have is the following

Numpad8::Up

Doesn't have correct behaviour when shift+numpad8 is pressed, the cursor moves up, but no text is selected. The following also don't work as I'd like (same behaviour as Numpad::8).

+Numpad8::Up
+Numpad8::+Up

If I remap a normal key, the selection behaviour is correct when shift is pressed:

w::Up

Any hints?

The reason I'm doing this is to make a CoolerMaster QuickFire TK's numeric keypad behave like it has a standard numeric keypad layout (I've some registry keyboard remapping happening as well, which is why I want the navigation behaviour with Numlock On).

2
The problem is: Shift + NumlockOnKey equals NumlockOffKeySchneyer

2 Answers

1
votes

It's possible, but it's a pain in the ass... compared to normal remapping.

Here is the normal behaviour of the Numpad8-key:

With numpad on:
num8: up
shift+num8: mark up

With numpad off:
num8: 8
shift+num8:up

So if you want to reverse that, what we want is this:

With numpad on:
num8: 8
shift+num8:up

With numpad off:
num8: up
shift+num8: mark up

This is how it could be achived:

*NumpadUp:: 
    If GetKeyState("NumLock", "T")
        SendInput, {Shift Down}{Up}
    Else If GetKeyState("Shift")
        SendInput, {Shift Up}{NumpadUp}
    Else
        SendInput, {Shift Up}{Numpad8}
Return


*Numpad8:: 
    If GetKeyState("Shift")
        SendInput, {Shift Down}{NumpadUp}
    Else
        SendInput, {NumpadUp}
Return

Now you just need to do the same thing for the other numpad keys that you want to reverse.

1
votes

Here is a different approach that uses a little hack to make it look like the Numpad toggles when pressing the numlock key. But it ensures that the numlock actually is always off and only the numlock light is changed.

SetNumLockState, Off
fakeNumlockOn := False
Return

NumLock::
    SetNumLockState, Off
    fakeNumlockOn := !fakeNumlockOn
    SetNumLockLEDs(fakeNumlockOn ? "on" : "off")
    Sleep, 100
    SetNumLockLEDs(fakeNumlockOn ? "on" : "off")
Return

SetNumLockLEDs(state) {
    Loop, 11
        KeyboardLED(2,state,A_Index-1)
}



/*

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