I am baffled... How do you make it so while you hold down a key it presses itself until you let go? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
YaBoi011011
Posts: 4
Joined: 20 Jan 2019, 20:25

I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

20 Jan 2019, 20:31

This is what I got so far:

Code: Select all

'::Suspend 
+w:: 
	While GetKeyState(w) = 1
	{
	Send w
	SetKeyDelay 30 
	}
User avatar
Tigerlily
Posts: 377
Joined: 04 Oct 2018, 22:31

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

22 Jan 2019, 18:29

Code: Select all

+w:: 
Send w
return
or from your code, you'll probably want to use SetKeyDelay, immediately preceding the Send command, and you need to add "" quotations around the w like this:

Code: Select all

'::Suspend 
+w:: 
	While GetKeyState("w") = 1
	{
	SetKeyDelay 30 	
	Send w
	}
without the quotations around the "w", w is seen as a variable (which is probably not set in your script), that's why you are having difficulties.
-TL
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?  Topic is solved

24 Jan 2019, 08:54

Y'all are forgetting your $ prefix

And putting SetKeyDelay in a loop like that is pointless, it only needs to be used once, at the beginning of the script
Plus getkeystate loops are just the wrong way to do this - It's all fair and well when there is only one hotkey, but if you try and do this with two keys at once, the script will not work properly.

This is the PROPER way to do this:

Code: Select all

#SingleInstance force

SetKeyDelay, 30
wState := 0	; Used to store current state of W, so we can filter out repeats when you hold it

$w::   ; Start spamming on press of W
	if (wState)
		return	; Filter key repeats
	wState := 1
	SetTimer, SpamW, 100
	return

$w up::   ; Stop spamming on release of W
	wState := 0
	SetTimer, SpamW, Off
	return

SpamW:
	Send {w}
	return
mast4rwang
Posts: 141
Joined: 19 Jul 2017, 09:59

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

24 Jan 2019, 09:23

evilC wrote:
24 Jan 2019, 08:54
Y'all are forgetting your $ prefix

And putting SetKeyDelay in a loop like that is pointless, it only needs to be used once, at the beginning of the script
Plus getkeystate loops are just the wrong way to do this - It's all fair and well when there is only one hotkey, but if you try and do this with two keys at once, the script will not work properly.

This is the PROPER way to do this:

Code: Select all

#SingleInstance force

SetKeyDelay, 30
wState := 0	; Used to store current state of W, so we can filter out repeats when you hold it

$w::   ; Start spamming on press of W
	if (wState)
		return	; Filter key repeats
	wState := 1
	SetTimer, SpamW, 100
	return

$w up::   ; Stop spamming on release of W
	wState := 0
	SetTimer, SpamW, Off
	return

SpamW:
	Send {w}
	return
So timers do not interfere with each other?
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

24 Jan 2019, 10:02

A fraction of how the other solution is blocking.
Recommends AHK Studio
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

24 Jan 2019, 11:56

mast4rwang wrote:
24 Jan 2019, 09:23
So timers do not interfere with each other?
There is only one timer in this example, but the point is that a while(GetKeyState()) loop locks up the current thread.
If, for example, you have a loop running, and you hit a hotkey with a GetKeyState loop in it, the loop in your main thread is suspended until the hotkey is released, which is not the case with my code.
See here: https://www.autohotkey.com/boards/viewtopic.php?t=19745
mast4rwang
Posts: 141
Joined: 19 Jul 2017, 09:59

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

24 Jan 2019, 14:38

evilC wrote:
24 Jan 2019, 11:56
mast4rwang wrote:
24 Jan 2019, 09:23
So timers do not interfere with each other?
There is only one timer in this example, but the point is that a while(GetKeyState()) loop locks up the current thread.
If, for example, you have a loop running, and you hit a hotkey with a GetKeyState loop in it, the loop in your main thread is suspended until the hotkey is released, which is not the case with my code.
See here: https://www.autohotkey.com/boards/viewtopic.php?t=19745
Wow that topic is yours? I immediately recognized it because I studied it long time ago.
It's so cool to read it once more now that I know so much more about coding than I used to back then :D
YaBoi011011
Posts: 4
Joined: 20 Jan 2019, 20:25

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

30 Jan 2019, 20:52

mast4rwang wrote:
24 Jan 2019, 14:38
evilC wrote:
24 Jan 2019, 11:56
mast4rwang wrote:
24 Jan 2019, 09:23
So timers do not interfere with each other?
There is only one timer in this example, but the point is that a while(GetKeyState()) loop locks up the current thread.
If, for example, you have a loop running, and you hit a hotkey with a GetKeyState loop in it, the loop in your main thread is suspended until the hotkey is released, which is not the case with my code.
See here: https://www.autohotkey.com/boards/viewtopic.php?t=19745
Wow that topic is yours? I immediately recognized it because I studied it long time ago.
It's so cool to read it once more now that I know so much more about coding than I used to back then :D
So if I wanted to bind multiple keys to the one script, would you just have to copy paste and just put a return at the bottom?
YaBoi011011
Posts: 4
Joined: 20 Jan 2019, 20:25

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

30 Jan 2019, 21:08

I did some testing and put in a few inputs to test. Is there a better way to do it than this?

Code: Select all

#SingleInstance force

SetKeyDelay, 20
qState := 0	; Used to store current state of Q, so we can filter out repeats when you hold it
wState := 0	; Used to store current state of W, so we can filter out repeats when you hold it
eState := 0	; Used to store current state of E, so we can filter out repeats when you hold it
aState := 0	; Used to store current state of A, so we can filter out repeats when you hold it
sState := 0	; Used to store current state of S, so we can filter out repeats when you hold it
DState := 0	; Used to store current state of d, so we can filter out repeats when you hold it

$q::   ; Start spamming on press of Q
	if (qState)
		return	; Filter key repeats
	qState := 1
	SetTimer, SpamQ, 100
	return

$q up::   ; Stop spamming on release of Q
	qState := 0
	SetTimer, SpamQ, Off
	return

$w::   ; Start spamming on press of W
	if (wState)
		return	; Filter key repeats
	wState := 1
	SetTimer, SpamW, 100
	return

$w up::   ; Stop spamming on release of W
	wState := 0
	SetTimer, SpamW, Off
	return

$e::   ; Start spamming on press of E
	if (eState)
		return	; Filter key repeats
	eState := 1
	SetTimer, SpamE, 100
	return

$e up::   ; Stop spamming on release of E
	eState := 0
	SetTimer, SpamE, Off
	return

$a::   ; Start spamming on press of A
	if (aState)
		return	; Filter key repeats
	aState := 1
	SetTimer, SpamA, 100
	return

$a up::   ; Stop spamming on release of A
	aState := 0
	SetTimer, SpamA, Off
	return

$s::   ; Start spamming on press of S
	if (sState)
		return	; Filter key repeats
	sState := 1
	SetTimer, SpamS, 100
	return

$s up::   ; Stop spamming on release of S
	sState := 0
	SetTimer, SpamS, Off
	return

$d::   ; Start spamming on press of D
	if (dState)
		return	; Filter key repeats
	dState := 1
	SetTimer, SpamD, 100
	return

$d up::   ; Stop spamming on release of D
	dState := 0
	SetTimer, SpamD, Off
	return

SpamQ:
	Send {q}
	return

SpamW:
	Send {w}
	return

SpamE:
	Send {e}

SpamA:
	Send {a}
	return

SpamS:
	Send {s}
	return

SpamD:
	Send {d}
	return
	return
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: I am baffled... How do you make it so while you hold down a key it presses itself until you let go?

31 Jan 2019, 05:38

You can shorten the code with a few more advanced techniques, especially because all your hotkeys use identical logic, only the key that gets sent changes.

Code: Select all

#SingleInstance force

SetKeyDelay, 20
keys := ["q", "w", "e", "a", "s", "d"]
SpamFns := {}
KeyStates := {}

for i, key in keys {
	fn := Func("KeyEvent").Bind(key, 1)
	hotkey, % "$" key, % fn
	fn := Func("KeyEvent").Bind(key, 0)
	hotkey, % "$" key " up", % fn
	SpamFns[key] := Func("DoSpam").Bind(key)
	KeyStates[key] := 0
}

KeyEvent(key, state){
	global SpamFns, KeyStates
	if (state && KeyStates[key])
		return
	KeyStates[key] := state
	t := state ? 100 : "Off"
	fn := SpamFns[key]
	SetTimer, % fn, % t
}

DoSpam(key){
	Send {%key%}
}

^Esc::
	ExitApp

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: garry, Google [Bot], marypoppins_1, mikeyww, OrangeCat, RussF and 150 guests