user34537
user34537

Reputation:

Toggle keys in autohotkey

My goal is mapping WASD to the 4 arrow buttons on the keyboard and make 1 'Suspend' the script while z exits it. That was easy enough. Now I'd like a and d only apply conditionally. I look at the docs and I have no idea what's wrong here. I think I'm either using the if statement wrong or Left/Right doesn't work in if statements in which case I have no idea what to do.

#SingleInstance
a::if(UseAD) Left
d::if(UseAD) Right
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp

Upvotes: 2

Views: 795

Answers (1)

errorseven
errorseven

Reputation: 2672

Try this:

#SingleInstance
$a::Send % UseAD ? "{Left}" : "a" 
$d::Send % UseAD ? "{Right}" : "d" 
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp

Okay now a break down.

Your If statement wasn't being evaluated correctly. The following line of code after the condition is met is what is run. Like so:

If (true)
    do this

Your Hotkey is also wrong for a Multi lined statement. Essentially a single lined Hotkey is a basically a Send command for whatever key or keys specified on that line (unless you specify an assignment/function/command etc...) it will act as a Send Command does. To have an If evaluation requires multiple lines. When you specify a hotkey and you want an evaluation that will require multiple lines you, and must return from a Multi-Lined Hotkey same a Sub Routine:

a::
   Code goes here
   more code
   etc..
Return 

b::AnotherHotkey 

etc..

Okay so lets plug this Logic in with your code:

#SingleInstance
a::
    if(UseAD) 
       Left
return

d::
   if(UseAD) 
       Right
return

1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp

If you run this you'll get an Error about the Text Left... that is because instead of our Hotkey acting as Send command it's acting as a Sub Routine so we have to specify Send command with Left:

a::
    if(UseAD) 
        Send, Left
return

But this isn't correct either, now it's sending the word Left instead of the Key left.. so again we have add Brackets around our named key like so:

a::
    if(UseAD) 
        Send, {Left}
return

Okay, now a and b are not being sent when UseAD is False, so we must Send them by specifying with Else like so:

a::
    if(UseAD) 
        Send, {Left}
    else
        Send, a
return

Now we run this code and press a or b get an Max Hotkeys reached message because our code is triggering the Hotkey in an Infinate loop. We need to specify our code in such a way that it will not trigger itself, like so:

$a::
    if(UseAD) 
        Send, {Left}
    else
        Send, a
return

If you notice we have added a $ symbol in front of our hotkey, this adds a keyboard Hook to that Hotkey and will prevent the the script from triggering that hotkey itself. This is now a complete working script but looks entirely different from the first code I posted. That is because I like typing less lines, if I can.

In the first code sample I'm using a Forced Expression % on the Send command and Ternary ? : to evaluate UseAD and if true send Left key if false send the letter, exactly the same as above code, just more concise.

Upvotes: 1

Related Questions