I am not able to switch left shift key to right shift key in AutoHotkey. I tried this code to switch but it worked perfectly for up, down, left and right arrows but didn't work for shift keys. Here's the code..
up::w
down::s
left::a
right::d
freerun::LShift
Numpad8::up
Numpad8::up
Numpad5::down
Numpad4::left
Numpad6::right
RShift::freerun
NumpadAdd::Enter
NumpadEnter::Backspace
You must use $ sign, otherwise lshift will fire rshift, which fires lahift. This will go on forever. $ prevents key from firing by send.
$LShift::RShift
$RShift::LShift
There are two important modifiers in AutoHotKey: ~ and $
Without these modifiers hotkey is intercepted and processed. It doesn't propagate. however k::m replaces k with m. k::k causes infinite loop.
~k::m allows k to go through and them prints m. Result is km
~k::k is a fork bomb. It sends kk for each k
$k::m is ignored if k came from AHK and fires if k came from keyboard.
h::k
$k::m
would then produce h -> k and k -> m replacements.
You need to use $LShift::RShift to avoid the loop.
Try this
LShift::RShift
RShift::LShift
You should use $ to prevent an infinite firing loop. Use this:
$LShift::RShift
$RShift::LShift
Related
I got stuck building an ahk shortcut script to increase / decrease Volume. The idea was to hold down LAlt+LShift and tap F12 to increase one step per tap.
The order in which LAlt and LShift are pressed shouldn't matter.
I came up with this so far:
!+::
While (GetKeyState("LShift","P")) and (GetKeyState("LAlt","P"))
{
F12::Send {Volume_Up}
}
Return
But somehow it increases the volume on holding LAlt and taping F12. LShift gets igronred..
What's wrong with that...
This
F12::Send {Volume_Up}
isn't a command, it's a hotkey assignment. You cannot use it within executable context. It is actually the short form for:
F12::
send {volume_up}
return
You wouldn't wanna have a return somewhere in between the lines which should be executed, would you.
As can be read in the documentation, you can only combine two Hotkeys for an action easily, like a & b::msgbox, you pressed a and b. E.g. for a,b AND c, you'd need some workaround like the crossed out, old answer below.
BUT you can add as many modifiers to your hotkey as you want. Modifiers are ! alt, + shift, # win and so on (please have a look # http://ahkscript.org/docs/Hotkeys.htm#Symbols).
So you can simply use
<!+F12::send {volume_up}
-
So, your aim is simply to have volume_up be fired when three Hotkeys are being pressed. You can achieve it like this:
#if getKeyState("LShift", "P")
*<!F12::send {volume_up}
#if
or
*<!F12::
if(getKeyState("LShift","P"))
send {volume_up}
return
For the meaning of * and < and other possible modifiers, see http://ahkscript.org/docs/Hotkeys.htm#Symbols
Your approach wasn't too bad. It would have worked if you had used the Hotkey command instead of an actual hotkey assignment. Still that would have been unneeded work
I'm new to autohotkey and I got stuck since other at the following, quite simple problem:
I want to map Alt + Shift + b to the c key.
And the following code:
!+b::c
(That is the whole script)
Doesn't work. When I press Alt + Shift + b at the same time, nothing happens.
What am I doing wrong?
!+b::c means as much as "when alt shift b is pressed, do c". But c is no action. State send c instead:
!+b::send c
Also note that when you want to execute more than just one send command, you can also expand the trunk and finish it with a return:
!+b::
send c
msgBox, other things
return
edit - wait a minute. If I remember right, a::b is a remapping of the a key to behave like b. So !+b::c should also work, shouldn't it. I'm confused now.
edit - well !+b::c does not send c but it sends !+c. This does not make any sense
Key Spam does not work so good.
Here is the code:
Loop
{
If GetKeyState("z", "P")
send w
If GetKeyState("g", "P")
send a
If GetKeyState("j", "P")
send d
If GetKeyState("h", "P")
send s
}
but when I hold z or zg together, then the original keys z and zg come all time once or twice between the w or wa output.
What can I write that the keys z+g+h+j never will be seen in the text file only w+a+s+d if I run this script?
Karoline, you are going about it the wrong way. Autohotkey was designed to do just what you really want to do.
As MCL says in his comment, you need only to map your keys to a send function
Put this in your script:
z::send w
g::send a
j::send d
h::send s
Now, when you push z it will type w instead.
Keep in mind that this is global over your entire computer unless you limit it to notepad using IfWinActive. The script will not exit on its own.
but this doenst work like i want
i want that i can press g+z same time or z+j same time or g+h same time or h+j same time
and that i get then awawawawaw or asasasasasasas or wdwdwdwdwdwdwd
that when i press 2 buttons same time it switch output ever 1 char
and when i use your answer and holz z it spams wwwwwwwwwwwwwwwwwwwwwwwwwwwww
and if if press then z+g it only continou spaming wwwwwwwwwwwwww not wawawawawawawawaw
thans
Karoline
According to your "answer", you are targeting a keyboard behaviour that's not standard. That is, using remapped keys with AHK or not, when pressing two letter keys simultaneously, solely the key pressed at last will continue firing.
Here's an example on how you can achieve an alternating behaviour instead:
SendMode, Input
g & z::
z & g::
Send, aw
return
g::Send, a
+g::Send, A
z::Send, w
+z::Send, W
You will have to explicitely define every custom combination with an & modifier, which makes them prefix keys. This comes with an upside and with a small downside: The upside is, you can now keep pressing your combination and it will continue firing two keys in an alternating fashion; no loop or the like required. The downside: You need to reconstruct prefix hotkeys' original behaviour. In our example, that's sending a lowercase or uppercase letter.
I want to create a hotkey that sends some key, and then another hotkey for that very just sent key, that in turn sends a third key.
That seems to be possible, using #InputLevel:
#InputLevel 1
a::b
#InputLevel 0
b::c
The above works as intended: By pressing a I get c.
However, I want not only to remap the first key: I want to do more before sending the key. So I thought I could just rewrite the above a little bit:
#InputLevel 1
Hotkey *a, foo
#InputLevel 0
b::c
foo:
; Do something more here …
SendInput {Blind}b
return
The above however does not work as intended: By pressing a I get b (not c).
Update: #Robert Ilbrink reminded me that you can execute more than one command, without using the Hotkey command:
#InputLevel 1
*a::
; Do something here …
SendEvent {Blind}b
return
#InputLevel 0
b::c
The above does give the intended effect: Pressing a results in c. However, I have to rephrase my problem. I guess the problem is: I need to set the hotkeys dynamically, which means I have to use the Hotkey command with a label (as far as I know). (Also notice that I use SendEvent above. Using SendInput produces a b. Odd.)
(End of update.)
I know there is a companion command to #InputLevel—SendLevel—which might be relevant. I've tried putting it many places but it has never made any difference.
So, that was the reduced, theoretical example. Remapping a to b to c is of course useless in reality (and the net result could of course be achieved by a::c). On to my use case. Just keep in mind that if it turns out that the "real" solution means doing what I'm trying to do some other way, I'm still interested in knowing more about #InputLevel and SendLevel, and why my example does not work as intended.
I'm working on implementing dual-role modifier keys. For example, send ) when pressing RShift alone, but RShift+key when pressed together with some other key. Basically, RShift on keydown, and RShift up and ) on keyup. However, that has one flaw: Even when combining RShift with some other key, ) is still sent. So the script needs to know when there has been a combination. My solution is to add hotkeys to all letter keys, the arrow keys and some other keys, like this:
for comboKey in filteredComboKeys {
Hotkey % "*" comboKey, Dual_comboKey
}
; Later in script:
Dual_comboKey:
; The following function lets the dual-role modifier keys know that they have
; been combined with another key (and a few other things, which I don't think
; are important for the issue.)
Dual.combo() ;
key := Dual.cleanKey(A_ThisHotkey)
SendInput {Blind}%key%
return
The above solution works very well for my purpose—except that the break all remappings and other hotkeys the user might have made: These simply never occur.
Why not:
a::
; Do something
Send, b
Return
As far as I can gather, #InputLevel doesn't bite on the Hotkey command. However, I stumbled on a solution for one of the snippets I originally posted:
Hotkey *a, foo
b::c
foo:
; Do something more here …
SendLevel 1
SetKeyDelay 0 ; Optional; Only affects this hotkey.
SendEvent {Blind}b
return
Note that SendEvent must be used. SendInput produces b. SendPlay produces nothing at all. I don't know why.
However, this technique won't work if you want to send the hotkey itself. Then you end up in an infinite loop. Using the keyboard hook does not help, since SendLevel overrides it.
So, again I have an answer the solves one of the initial examples, but does not help me in reality. I need to send the hotkey itself. I guess I have to let the user remap their keys using my script. Sigh.
Update:
I've published my dual-role modifiers script now, in case anyone is interested in more details, and how I deal with the problems.
Update:
I've updated my dual-role modifiers script. I now stay away from the Hotkey command. It's easier when dealing with this kind of thing, I think.
By now (starting Autohotkey 1.1.01), this can be achieved quite easily like so:
~Shift up::
IfInString, A_PriorKey, Shift
{
Send )
}
return
I would like to assign the number 1 so that when I press it the result is to send to the computer qx and then enter.
1:: Send, qx{ENTER}
q:: Send, jx{Enter}
But then I also want to assign the letter q to send something else to the computer. Is it possible to do this? I'm concerned that if I assigned 1 to something that involves q, then whenever I press 1 q will also be called, and we'll end up in a loop.
Is there some way to fix it so AHK 'knows' when qx gets sent that I don't want to call the q function (and hence jx)?
Good thinking. The AutoHotKey developers have thought about that and introduced the $ to prevent this "loop"
example:
$1::Send, q
$q::Send, 1
Pressing 1 will generate a q, but due to the $ it will NOT trigger the second hotkey and vise versa.
So by pacing a $ in front of the q, you will prevent this loop in your situation.