Capslock + s + m in AutoHotKey - autohotkey

My full goal is to be able to hold down Capslock + s, which will convert the keys uiojklm,. to work like the 10-key number pad.
So as a first step, I am trying to map Capslock + s + m to the number 1
SetCapslockState AlwaysOff
Capslock & s::
keywait, m, d, t0.6
If (!ErrorLevel) {
SendInput {1}
} Return
I based my current code off of the answer here: Alt + Space + key in autohotkey
When I press Capslock + s + m, it prints out m1. How do I stop the m from printing?

Here is an alternative solution. You MUST have AutoHotKey_L for this to work since the traditional AutoHotKey does not support #if.
CapsLock & s::
Flag:=!Flag
If (Flag)
TrayTip, AutoHotKey, Numpad ON, 1
Else
TrayTip, AutoHotKey, Numpad OFF, 1
Return
#If (Flag)
m::Send, 0
k::Send, 1
#If
In the first block you toggle a Flag to True/False with CapsLock + s and you show the status with a traytip, then you define the behaviour of certain keys in the next block. Alternatively you could delete the first block and replace the #if (Flag) line with:
#If (GetKeyState("CapsLock", "P") and GetKeyState("s", "P"))
Update:
Tried the following with varying results. The first (commented out) code does use CapsLock + s, but apparently pressing the s key prevents AutoHotKey from seeing certain other key presses (here the letters n,m,i,o,p worked but j,k,l which are on the same hight/scanline on the keyboard were NOT detected)
SetCapsLockState, alwaysoff
/*
Capslock & s::
While, (GetKeyState("CapsLock", "P") and GetKeyState("s", "P"))
{
Input, MyKey, I L1 T0.5
TrayTip, Key:, %MyKey%
if (MyKey = "m")
Send, 1
if (MyKey = "i")
Send, 2
if (MyKey = "k")
Send, 3
if (MyKey = "j")
Send, 4
if (MyKey = "o")
Send, 5
if (MyKey = "p")
Send, 6
}
Return
*/
Just using CapsLock (also on the same like as j,k,l) worked, but that is not what you wanted.
Capslock::
While, (GetKeyState("CapsLock", "P"))
{
Input, MyKey, I L1 T0.5
TrayTip, Key:, %MyKey%
if (MyKey = "m")
Send, 1
if (MyKey = "i")
Send, 2
if (MyKey = "k")
Send, 3
if (MyKey = "j")
Send, 4
if (MyKey = "o")
Send, 5
if (MyKey = "p")
Send, 6
}
Return

Related

Remap alphabetic keys to numeric when NumLock is On with AutoHotKey

I have a laptop DELL XPS 13 9310 that doesn't come with physical or togglable numeric keys and visible NumLock key. However, I have just discovered that I can press Fn+B to toggle the NumLock state as can be seen on a virtual keyboard.
Can AHK detect the NumLock state and rewrite M JKL UIO to 0 123 456?
And how do I write this detection mechanism?
I woul'd try something like:
#Persistent
#if GetKeyState("NumLock", "T")
ToolTip % GetKeyState("NumLock", "T")
M::
Send, 0
return
J::
Send, 1
return
K::
Send, 2
return
L::
Send, 3
return
U::
Send, 4
return
I::
Send, 5
return
O::
Send, 6
return
This is a bit grost, but, probably will do the job

Layer based Keyboard using AutoHotKey: Change modifiers single press, hold, and double press behavior

folks,
I want to create a layer based keyboard using AutoHotkey. Basicly, I want to achieve what shift already does: modify each key when a modifier is used.
I want to improve regular shift in the following:
press modifier once: only change layer for next character
hold modifier: change layer as long as modifier is down
press modifier twice: enter layer mode, like capslock. (end by another press)
Modifiers: LAlt, RAlt, LControl, RControl (CapsLock, Shift)
How cas I accomplish this?
what I found so far on stackoverflow:
This code allows for shift to be pressed and released for the next character
$*LShift::
SendInput, {LShift Down} ; press shift
Input, Key, L1 M V ; wait for input character
If GetKeyState("LShift", "P") ; if shift still pressed, wait for release
KeyWait, LShift
SendInput, {LShift Up} ; send input with shift down, the shift up
Return
this code turns a double shift press into CapsLock
LShift::
KeyWait, CapsLock ; wait to be released
KeyWait, CapsLock, D T0.2 ; and pressed again within 0.2 seconds
if ErrorLevel
return
else if (A_PriorKey = "CapsLock")
SetCapsLockState, % GetKeyState("CapsLock","T") ? "Off" : "On"
return
#If, GetKeyState("CapsLock", "P") ; hotkeys go below
a::b
#If
But I am not experienced enough with AHK to bring this together. My goal is to have something like
Modifier::
; code that makes the modifier behave like expected: single press, hold, double press
Return
#If, GetKeyState("Modifier", "P") ; List of key remaps in specific layer
#If
I hope this is specific enough and that you can help me out here.
thanks!
Assign the corresponding Booleam values (true or false) to the variables "Double_LAlt" and "Double_LAlt_holding" in order to create context-sensitive hotkeys depended on their values:
LAlt::
ToolTip,,,, 3
ToolTip,,,, 4
Double_LAlt := false
; Press twice or press twice and hold LAlt within 0,2 seconds
If (A_PriorHotKey = "~LAlt Up" AND A_TimeSincePriorHotkey < 200)
{
Sleep, 200
If GetKeyState("LAlt","P")
{
ToolTip,,,, 4
ToolTip, Double_LAlt_holding,,, 2
Double_LAlt_holding := true
}
else
{
ToolTip,,,, 4
ToolTip, Double_LAlt,,, 3
Double_LAlt := true
}
}
If !((Double_LAlt_holding) || (Double_LAlt)) ; "!" means "NOT" and "||" means "OR"
ToolTip, LAlt_holding,,, 1
return
~LAlt Up::
ToolTip,,,, 1
ToolTip,,,, 2
Double_LAlt_holding := false
Sleep, 100
If (A_TimeIdlePhysical > 100)
Tooltip, PriorHotKey = LAlt Up,,, 4
SetTimer, RemoveTooltip, 1000
return
#If (Double_LAlt_holding) ; If this variable has the value "true"
<!a:: MsgBox, a while Double_LAlt_holding ; "<!" means "LAlt"
<!1:: MsgBox, 1 while Double_LAlt_holding
#If (Double_LAlt)
a:: MsgBox, a after Double_LAlt
1:: MsgBox, 1 after Double_LAlt
; Press a key within 2 seconds after releasing LAlt:
#If (A_PriorHotKey = "~LAlt Up" AND A_TimeSincePriorHotkey < 2000)
a:: MsgBox, a after LAlt Up
1:: MsgBox, 1 after LAlt Up
#If GetKeyState("LAlt","P")
a:: MsgBox, a while LAlt_holding
1:: MsgBox, 1 while LAlt_holding
#If
RemoveTooltip:
If (A_TimeSincePriorHotkey > 2000) ; 2 seconds
ToolTip,,,, 4
return

Long-press = Capitalize

Intended Hotkey Function: Capitalize character if key pressed longer than 0.2s
Occurring Problem: When typing "vbnm" in a row in a fast manner (which means I am pressing a the next key while still holding down the previous one) then AHK outputs just x-times the key that was pressed first, resulting here in "vvvv".
That is the code. Please help me out (y) :-)
$y::
$x::
$c::
$v::
$b::
$n::
$m::
key := SubStr(A_ThisHotkey, 2)
;MsgBox, %key% ;it recognizes/shows all keys pressed correctly,
;but in the end it prints just x-times the key that was pressed first
;whereby x is the number of keys pressed very quickly in a row
KeyWait, %key%, T0.2 ;Long press = capitalize
If ErrorLevel
SendInput +%key%
Else
SendInput %key%
Return
So finally this code seems to work, beside the little inconvenience when holding the key much too long, resulting in e.g. "Oo".
;For normal characters ......
$x::
$c::
$v::
$b::
$n::
$m::keyFunc(SubStr(A_ThisHotkey, 2))
keyFunc(key) {
Critical
KeyWait, %key%, T0.3 ;Long press = capitalize
SendInput % ErrorLevel ? Format("{:U}", key) : key
Return
}
;For special characters ......
$2::
$3::
$4::
$5::
$6::
$7::
$8::
$9::
$sc01A:: ;ü
$sc027:: ;ö
$sc028:: ;ä
$sc00C:: ;ß
$sc033:: ;,
$sc034:: ;.
$sc035:: ;-
$sc01B:: ;+
$sc02B:: ;#
$sc00D:: keyFunc2(SubStr(A_ThisHotkey, 2))
keyFunc2(key) {
Critical
KeyWait, %key%, T0.3 ;Long press = capitalize
If ErrorLevel
SendInput +{%key%}
Else
SendInput {%key%}
Return
}
try:
$y::
$x::
$c::
$v::
$b::
$n::
$m::keyFunc(SubStr(A_ThisHotkey, 2))
keyFunc(key) {
KeyWait, %key%, T0.3 ;Long press = capitalize
SendInput % ErrorLevel ? Format("{:U}", key) : key
Return
}

Disable/Block a Key with another Key while its pressed and held down

So in this game im moving my charachter with the WASD keys, but if i hold down the A and D key at the same time,
the game register that as a forward movement (W key |) so the charachter starts to move forward instead of the strafe actions (Left) \ (right) /.
So i need a code which is prevents the A and D key simultaneous pressing.
CHECK THIS GIF, SO U CAN SEE WHAT I MEAN!
I want A and D override each other (Im not using the W key), because if i hit both A and D at the same time my character moves forward, not like this \ /
and i want to avoid the forward movements.
I want insantly changed fast Left \ and Right / strafing only.
Here is the code what i got so far:
~a::
If (GetKeyState("d", "p"))
{
Send {d up}
d = 0
}
Return
~d::
If (GetKeyState("a", "p"))
{
Send {a up}
a = 0
}
Return
a up::
If (d)
{
Send {d down}
d = 0
}
Return
d up::
If (a)
{
Send {a down}
a = 0
}
Return
Basicly this code almost working.
The problem is if i don't change the numbers i can't change directions continuously i need to let go the keys. It stops after 1 direction change. If i change the numbers its working, but after a few direction change its getting toggled either left or right. Even if i let it go its moving left or right....
Any ideas? thx
This should work. Try it and let me know.
$*a::
$*d::
SendInput, {a Up}{d Up}
StringReplace, hk, A_ThisHotkey, % "$*"
SendInput, {%hk% Down}
KeyWait, % hk
Send, {a Up}{d Up}
return
EDIT: You can play around with the code below. Maybe it will help you out
#SingleInstance, force
#Persistent
#NoEnv
#MaxThreadsPerHotkey, 1
~a & d::
~d & a::
Send, {a up}
key := "d"
SetTimer, pressdown, 10
return
~d::key := "d"
~a::key := "a"
~a up::key := "d"
~d up::key := "a"
pressdown:
if GetKeyState(key, "p")
{
SendInput, {%key% down}
SetTimer, pressdown, 30
}
else {
SetTimer, pressdown, Off
SendInput, {%key% up}
}
return
This script cannot allow A, or D to be simultaneously pressed.

Shift Key Training Wheels and Shift Parenthesis Remap

I'm looking to use AutoHotKey to modify the functionality of my shift keys. The functionality is described in Steve Losh's Blog entry here. Specifically, I'd like my shift keys to do the following:
If LShift or RShift is pressed and released in under 300 ms with no other keys being pressed in between, send ( or ), respectively.
If LShift and RShift are "rolled" together (press LShift, press RShift, release LShift, release RShift, etc.) in under 300ms, send () or )(.
If a shift key is used improperly (LShift and S, RShift and K, etc.) then nothing happens.
I've been having issues with the 300ms requirement and the "rolling" functionality. Specifically, I'm having issues with only being able to detect when the key is released due to the hotkey combos such as:
LShift & 0:: return
This is where I'm at so far:
LShift::
Send {LShift Down}
KeyWait, LShift
Send {LShift Up}
if (A_TimeSinceThisHotkey < 300){
if (A_PriorKey = "LShift")
{
Send {)}
}
}
return
I don't see a reason to use a 300 ms timeout anyway, it seems unreliable and unnecessary.
Have a look at this commented code, it is short and efficient, and seems to meet all of your requirements:
LShift::Send, (
RShift::Send, )
LShift & RShift:: Send, ()
RShift & LShift:: Send, )(
/* Put your unwanted combinations here
* and let them do nothing
*/
LShift & q::return
RShift & y::return
Edit:
Since LShift and RShift already are prefix hotkeys, I left out the trick described here.
MCL's answer is close but when I tested it I found that shift-clicking didn't select text. Here's a version with a passthrough to allow shift-clicking to work.
;shift to parens
LShift::Send, (
RShift::Send, )
LShift & RShift:: Send, ()
RShift & LShift:: Send, )(
;passthrough for shift-click
LShift & LButton::
Send, {LShift Down}{LButton}
Send, {LShift Up}
RShift & LButton::
Send, {RShift Down}{LButton}
Send, {RShift Up}
I don't think the 300ms timeout is possible without either very deep understanding of autohotkey's implementation or actual modification to autohotkey. When I tried to get it to work (using http://www.autohotkey.com/board/topic/98742-remapping-shift-key/) I found that A_PriorHotkey was not consistently populated. I don't think that variable was meant to work with modifier keys this way.
I felt compelled to figure this one out. Here you go!
I basically created a hotkey for every Shift + Letter key combination in order to send the correct key case and also set the Abort value. The Abort value is then referenced whenever one of the Shift keys is pressed in order to determine whether or not to send the corresponding ( or ).
The "Rolling" was accomplished by creating a Hotkey for LShift + RShift (and the opposite). It then looks to see which key is released first to determine () or )(.
Accept if this was what you were looking for!
Loop 26
{
Hotkey, % "~LShift & " Chr(A_Index+96), LetterKey ; Hotkeys for A-Z
Hotkey, % "~RShift & " Chr(A_Index+96), LetterKey ; Hotkeys for A-Z
}
Return
RShift::
LShift::
Abort := 0
keyDown := A_TickCount
Keywait, % A_ThisHotkey
duration := A_TickCount - keyDown
If (duration < 200) and (Abort = 0)
SendInput % (A_ThisHotkey = "LShift") ? "(" : ")"
Send {LShift Up}
Return
RShift & LShift::
LShift & RShift::
Keywait, LShift
If GetKeyState("RShift", "P")
{
Keywait, RShift
Send ()
}
Else
Send )(
Return
LetterKey:
SendInput, % "+" SubStr(A_ThisHotKey, 0, 1)
Abort := 1
Return
EDIT:
Hmm, I seem to be having the same problem as you. I always get a duration of 0 due to the hotkeys.
I found and modified this script on the AutoHotKey Forums. (The original script was prone to type "K(" when you meant to type "K" if you type too quickly, so I've modified it so that shouldn't happen any more)
$LShift Up::send, % getkeystate("LShift") ? "{LShift Up}" : ""
$RShift Up::send, % getkeystate("RShift") ? "{RShift Up}" : ""
~$LShift::
KeyWait, LShift, T0.1 ; wait 100ms to check shift state
if (A_PriorKey = "LShift")
{
send, % getkeystate("LShift") ? "{LShift Down}" : "("
}
KeyWait, LShift
return
~$RShift::
KeyWait, RShift, T0.1 ; wait 100ms to check shift state
if (A_PriorKey = "RShift")
{
send, % getkeystate("RShift") ? "{RShift Down}" : ")"
}
KeyWait, RShift
return