Hold/Toggle key script

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Coal48
Posts: 2
Joined: 17 Dec 2015, 09:20

Hold/Toggle key script

17 Dec 2015, 09:30

Hello,

I'm a newbie and I don't really have the patience to actually learn scripting, so if someone could help me, that would be grand

I want to make a script that holds down a key for me, simple as that but I can't make it work by myself, here's what I tried:

Code: Select all

z::
{
	Sendinput, {v down}
	Return
}

when pressing "z" it just presses "v", it doesn't hold it down, it needs to hold it, toggle it on/off.
Shadowpheonix
Posts: 1259
Joined: 16 Apr 2015, 09:41

Re: Hold/Toggle key script

17 Dec 2015, 10:27

If you want it to just hold the key down...

Code: Select all

z::
KeyDown := !KeyDown
If KeyDown
	SendInput {v down}
Else
	SendInput {v up}
Return
If what you actually want is for it to press the key repeatedly (which is what you often get if you physically hold the key down on your keyboard)...

Code: Select all

z::
RepeatKey := !RepeatKey
If RepeatKey
	SetTimer, SendTheKey, 100	; The "100" here is the number of milliseconds between repeats.
Else
	SetTimer, SendTheKey, Off
Return

SendTheKey:
SendInput v
Return
Coal48
Posts: 2
Joined: 17 Dec 2015, 09:20

Re: Hold/Toggle key script

17 Dec 2015, 10:43

[quote="Shadowpheonix"]If you want it to just hold the key down...

Code: Select all

z::
KeyDown := !KeyDown
If KeyDown
	SendInput {v down}
Else
	SendInput {v up}
Return
I just want to hold it down, I tested your script and it doesn't work

when pressing "z", it pressed "v" (not holding it), pressing "z" again doesn't do anything and then pressing it again, presses "v" once

Actually, it does work. it does the strange behavior in notepad but I didn't actually test it in-game when I posted (idiot)

thanks a lot for helping me
Last edited by Coal48 on 17 Dec 2015, 12:43, edited 2 times in total.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Hold/Toggle key script

17 Dec 2015, 11:58

Shadow's second code should do what you want.

There's two things with a keyboard: The physical key presses trigger a "down" and "up" event upon pressing and releasing, respectively. AHK can emulate that by using {Key down} and {Key up} keystrokes.

Here's where confusion sets in. Your Keyboard driver will take over and emulate a series of rapid up/down key strokes when you are holding down the key. This is the autorepeat behavior very common place on keyboards. So Shadow's second example accomplishes that.

A thing to note is that AHK will bypass they keyboard driver, and that's why you have to manually define a repeat behavior within the AHK script.

You can check out alternative approaches in this thread: (Note: This is from the old forums) http://www.autohotkey.com/board/topic/6 ... re-thread/
helming

Re: Hold/Toggle key script

07 Dec 2016, 03:43

Hi, I'm new to the ahk scripting. trying to read out tutorials but it's too much.

I wonder what

KeyDown := !KeyDown

means.

I guess the KeyDown is a variable, and it's content is !KeyDown.

! menas 'logically not', so content of the "KeyDown" is not KeyDown...

What's that supposed to mean?


P.S Sorry for my poor english. I'm not good at it.
SirRFI
Posts: 404
Joined: 25 Nov 2015, 16:52

Re: Hold/Toggle key script

07 Dec 2016, 07:53

You guessed right.
When a variable has any other value than 0, it's considered TRUE. Now, if You negate it, it will become FALSE. So, what KeyDown := !KeyDown does is overwrite self with negated bool value (true becomes false, false becomes true). Keep in mind doing this to a false value (0) will end in true value (1, not what it originally was), which is enough in the code above: toggle on/off.

Here's a sample if You're willing to understand what I mentioned.

Code: Select all

; 3 - true
myVar := 3
MsgBox % myVar

; becomes 0 - false
myVar := !myVar
MsgBox % myVar

; becomes 1 - true
myVar := !myVar
MsgBox % myVar
Use

Code: Select all

[/c] forum tag to share your code.
Click on [b]✔[/b] ([b][i]Accept this answer[/i][/b]) on top-right part of the post if it has answered your question / solved your problem.
helming
Posts: 25
Joined: 07 Dec 2016, 15:01

Re: Hold/Toggle key script

07 Dec 2016, 16:06

Just signed up realizing that I couldn't modify the post without being a member.

Thank you for your help, SirRFI.
SirRFI wrote:what KeyDown := !KeyDown does is overwrite self with negated bool value (true becomes false, false becomes true). Keep in mind doing this to a false value (0) will end in true value (1, not what it originally was)
Now I understand that, but still not completely clear. I've spent an hour trying to understand what you wrote and testing a couple of thing on my own.

Looking at the sample code you wrote

Code: Select all

; 3 - true
; 3 - true
myVar := 3
MsgBox % myVar

; becomes 0 - false
myVar := !myVar
MsgBox % myVar

; becomes 1 - true
myVar := !myVar
MsgBox % myVar
and a little modification to it

#1

Code: Select all

; 3 - true
myVar := !myVar
MsgBox % myVar		;output is 1

myVar := !myVar
MsgBox % myVar		;output is 0
#2

Code: Select all

; 3 - true
myVar := !efgdr
MsgBox % myVar		;output is 1

myVar := !myVar	
MsgBox % myVar		;output is 0
I guess myVar doesn't have any value before it's defined at the first line on #1, so !myVar doesn't have any value either, equivalent to 'not zero', hence resulting in TRUE. Similar logic goes to #2
Is that correct?
SirRFI
Posts: 404
Joined: 25 Nov 2015, 16:52

Re: Hold/Toggle key script

09 Dec 2016, 08:32

If variable is not defined, it defaults to FALSE (0). In both #1 and #2 You negate an undefined variable, so You assign "NOT FALSE". As mentioned earlier, negated false (NOT FALSE) is TRUE.
Use

Code: Select all

[/c] forum tag to share your code.
Click on [b]✔[/b] ([b][i]Accept this answer[/i][/b]) on top-right part of the post if it has answered your question / solved your problem.
Fatbunny

Re: Hold/Toggle key script

27 Mar 2017, 12:50

z::
RepeatKey := !RepeatKey
If RepeatKey
SetTimer, SendTheKey, 100 ; The "100" here is the number of milliseconds between repeats.
Else
SetTimer, SendTheKey, Off
Return

SendTheKey:
SendInput v
Return

Is there a toggle built into this script?...If so what needs to be changed so that when I toggle with my Mouse button (XButton2) it causes the w key to be pressed down?
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Hold/Toggle key script

27 Mar 2017, 18:23

That script is toggled with Z and will send v. Change z for XButton2 and v for w.
Krypto

Re: Hold/Toggle key script

23 Aug 2017, 05:47

z::
RepeatKey := !RepeatKey
If RepeatKey
SetTimer, SendTheKey, 100 ; The "100" here is the number of milliseconds between repeats.
Else
SetTimer, SendTheKey, Off
Return

SendTheKey:
SendInput v
Return

How do I make the above to press space and hold it down until I press z again instead of typing vvvvvv all the time. Im a noob to coding :-)

/Krypto
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Hold/Toggle key script

23 Aug 2017, 11:05

You want to take a different approach than a timer. There are multiple approaches, but I like this one:

Code: Select all

z::
Send {Space down} ; this holds the space key down
KeyWait, z ; waits for you to release z
KeyWait, z, D ; waits for you to press Down z again
Send {Space up}
KeyWait, z ; waits for you to release z
return
Technically the third KeyWait there (the second for z release) may not be necessary, but it does prevent the hotkey from being triggered again because you held down z too long.

You could also, for the sake of a pattern, put KeyWait, z, D as the very first line. But you don't need to because you will be pressing z anyway to activate the hotkey, so no need to check. (But I can say, it is possible to activate the z hotkey without pressing z, but since that is not your use case and you won't program explicitly for it, don't worry.)
Krypto
Posts: 4
Joined: 23 Aug 2017, 12:31

Re: Hold/Toggle key script

23 Aug 2017, 12:37

Just made an account, thats easier :)
The below is working, however I want it to start when I press F1 and stop when I press F2, how do I do that?
F1::
RepeatKey := !RepeatKey
If RepeatKey
SetTimer, SendTheKey, 100 ; The "100" here is the number of milliseconds between repeats.
Else
SetTimer, SendTheKey, Off
Return

SendTheKey:
SendInput v
Return
Krypto
Posts: 4
Joined: 23 Aug 2017, 12:31

Re: Hold/Toggle key script

23 Aug 2017, 12:39

Dobbelt post, sorry.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Hold/Toggle key script

23 Aug 2017, 20:40

Code: Select all

F1::SetTimer, SendTheKey, 100
F2::SetTimer, SendTheKey, Off
Of course, keep your SendTheKey label.
Krypto
Posts: 4
Joined: 23 Aug 2017, 12:31

Re: Hold/Toggle key script

24 Aug 2017, 04:09

Thanks for the reply, so its like this:

F1::
RepeatKey := !RepeatKey
If RepeatKey
SetTimer, SendTheKey, 100 ; The "100" here is the number of milliseconds between repeats.
Else
F2::SetTimer, SendTheKey, Off
Return

SendTheKey:
SendInput v
Return
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Hold/Toggle key script

24 Aug 2017, 10:38

Nope. You don't need any If or Else statement if you are saying F1 = On and F2 = Off. The RepeatKey variable is only necessary if you are using one hotkey for both On and Off.

What you might have constructed there is a hotkey where F1 can turn on and off the hotkey (but not always flip it to opposite, it might go Off -> Off -> On with each -> representing an F1 press) and F2 always turns it off. I haven't tested the code.
Krypto
Posts: 4
Joined: 23 Aug 2017, 12:31

Re: Hold/Toggle key script

24 Aug 2017, 11:38

So, how should the code look exactly? :D sorry for the very noob questions, I have 3 friends that im playing a game with and we are all getting aids in our hands because we have to hold down mouse1 and we can instead bind walk to v and just use F1 and F2 to start stop it with this script
helming
Posts: 25
Joined: 07 Dec 2016, 15:01

Re: Hold/Toggle key script

15 Oct 2017, 21:50

Hello, guys. I have a question.

Code: Select all

p::
{
KeyDown2 := !KeyDown2
If KeyDown2
	Send {Ctrl down}
Else
	Send {Ctrl up}
Return
}

q::
{
KeyDown3 := !KeyDown3
If KeyDown3
	Send {w down}
Else
	Send {w up}
Return
}

l::
{
	SendInput {Ctrl down}
	Sleep, 1700
	SendInput {Ctrl up}
Return
}
I have this script, but 'p' doesn't work as intended. Ctrl is held down with pressing p, but it isn't released even if I press p again. Whereas Hotkey 'q', 'l' work as intended.

Moreover as p is assigned as hotkey, it shouldn't be input. But if I press p multiple times, it is recognized by computer while ctrl is being held down. In other words, com thinks I pressed Ctrl + p multiple times.
Then I changed Ctrl to Shift, It doesn't work neither.

I have no idea what's wrong.

Thanks in advance.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Hold/Toggle key script

15 Oct 2017, 22:12

@Krypto, something like this. (I assume Mouse1 is XButton1 for AutoHotkey; see KeyList.)

Code: Select all

#If ; these hotkeys are always active
F1::flag_var:=true
F2::flag_var:=false

#If flag_var ; is true
v::XButton1
or you can try

Code: Select all

v::
Send {XButton1 down}
KeyWait, v
Send {XButton1 up}
return
----

@helming, this is because when you send Ctrl down, all your key strokes, even those physical ones, are considered to be Ctrl+that key. So when you press p, all subsequent presses of p will be a Ctrl+P. This does not activate your hotkey. To make it work, you stack your hotkeys as

Code: Select all

^p::
p::
; KeyDown2 stuff
or you can use the * modifier for a *p:: hotkey. This makes the hotkey activate regardless if ctrl is up or down, and if shift is up or down, and if alt is up or down, and if the windows key is up or down.

This is why your computer is thinking you pressed Ctrl+p multiple times.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: mikeyww and 192 guests