I don't know why exactly that doesn't work, I'll try to find out after this post and will edit that in if I find out.
However, there are many things wrong (bad practice) in that script, so we'll be able to get you a working version easily.
Firtly, there is no need to use multiple send commands. Just put all the characters in one send command.
Secondly, there is no need to wrap those keys around a {}
. That's only done when you want to escape keys that have special. For example wrapping !
in {}
would send the literal !
key instead of the ALT key. (In AHK !
indicates the ALT modifier key)
Ok, so now your script looks like this
F7::
Loop
Send, 1----2----
return
F8::Pause
I also removed the braces around the loop, they're not needed for a one-liner. And added the return
at the end of the hotkey, even though technically not needed here, but it kind of belongs there. With return
you stop code execution, and that's how you end a non-one-liner hotkey statement (not needed for one-liners).
But in your case the code execution will never escape the loop, so it doesn't really matter.
But that the loop still doesn't get interrupted by your pause hotkey. If you were to use SendInput
it would work. So just replace Send
with SendInput
.
It would also be very very very much faster at sending the keys and also more reliable. If it's too fast even, you could switch back to Send
and tune the speed with SetKeyDelay
.
Even better than using any way of sending those keys, would be setting the text to your clipboard and sending ctrl+v. Now that's fast and reliable. But maybe a bit excessive since your string to send is not that long. But if it gets longer, you'll surely want to do that.
Of course whether or not that works depends to what you're sending input to. Here's a minimal example for that:
Clipboard := "This is a long string that's going to be sent instantly by the use of pasting it in.`nThis is a long string that's going to be sent instantly by the use of pasting it in."
F7::SendInput, ^v
But still, all of this is bad practice because we're using a loop. And especially loop that's under a hotkey.
Now lets get onto some better ways of doing this. But first let me say that none of this make any actual difference in practice if your whole script is just those two hotkeys and nothing more. But still, for future reference, when you might make bigger and better scripts, I'd like to show some better ways of doing this.
Firstly, by pausing you just pause the whole script (so also all loops and timers, etc). But you never exit the loop. Always when you unpause, the loop will still be running there. Might not be desired.
You could make the loop include some condition under which to break the loop. Quick and minimal example of breaking the loop when a condition is met:
F7::
BreakLoop := false
Loop
{
if (BreakLoop) ;if true
break
ToolTip, % A_TickCount ;built in variable that holds the time, in ms, since our system was started
}
return
F8::BreakLoop := true
But actually, even the usage of a loop can be bad practice. If we have a bigger script we'd want the loop to be something that's just running on the background. But a loop wont do that.
So, secondly, using a timer instead of a loop.
Basic example:
F7::SetTimer, OurTimersCallback, 0 ;0 as in execute timer every "0" ms (as fast as possible)
F8::SetTimer, OurTimersCallback, Off ;turn off
OurTimersCallback()
{
ToolTip, % A_TickCount
}
Sweet, but we can do even better. Lets use the same hotkey to toggle on/off, so we don't need two different hotkeys:
Toggle := true
F7::
if (Toggle)
{
SetTimer, OurTimersCallback, 0
Toggle := false
}
else
{
SetTimer, OurTimersCallback, Off
Toggle := true
}
return
OurTimersCallback()
{
ToolTip, % A_TickCount
}
Nice, but believe it or not, we can do even better, though this part makes no difference in practice. But we can use a one-liner for the hotkey statement:
F7::SetTimer, OurTimersCallback, % (Toggle:=!Toggle) ? 0 : "Off"
OurTimersCallback()
{
ToolTip, % A_TickCount
}
Phew, ok, well that's surely a bit confusing. Let me type out the explanation for what happens and why it works.
% ( ) ? <value> : <value>
So what is this?
With %
force the current parameter of command we are in the behave in expression syntax. So instead of interpreting what we type literally (as one string), it understand the cool stuff we're doing.
And then ( ) ? <value> : <value>
is a ternary operator.
If the statement inside ( )
evaluates to true, we use the value that's before :
(0 in our case), and if it evaluates to false, we use the value that's after :
(the string Off in our case).
Toggle:=!Toggle
The variable Toggle
, like any variable, starts off with the default value of nothing, which evaluates to false
in this example, so we'll just say Toggle
starts off with the value false
to keep things a bit more simple.
With :=
we assign an expression (simply said, a value (in this case)) to Toggle
(if you don't already know the difference between =
and :=
, that's something you should learn, but that's an other thing)
!Toggle
means the opposite of the value Toggle
holds.
So opposite of false
(the default value any variable holds at the beginning) is true
Ok, so now Toggle
holds the value true
.
And our ternary's statement, (Toggle:=!Toggle)
is checking if the expression inside the brackets ( )
evaluates to true.
Well it did, so we choose the value for true in our ternary.
Next time around (when we hit F7 again), the variable Toggle
already holds the value true
.
Then we do the same stuff again. We assign !Toggle
to Toggle
. This time the opposite value is false
, so the if statement evaluates to false, so we choose the value for false in our ternary instead.
And then when F7 is hit once again, we change the value of Toggle
to its opposite again.
Toggle
's value keeps changing between true, false, true, false, true,... and this is how we achieve a very nice, short, toggle.
Very long post, I hope someone learns something, or at least finds it interesting.
Well, at least I enjoyed writing it.