Page 1 of 1

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

Posted: 20 Jan 2019, 20:31
by YaBoi011011
This is what I got so far:

Code: Select all

'::Suspend 
+w:: 
	While GetKeyState(w) = 1
	{
	Send w
	SetKeyDelay 30 
	}

I would also find it useful if there was a way to make a onscreen keyboard you can click on to use letters.

Posted: 21 Jan 2019, 13:51
by YaBoi011011
Can someone give me the knowledge?

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

Posted: 22 Jan 2019, 18:29
by Tigerlily

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.

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

Posted: 24 Jan 2019, 08:54
by evilC
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

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

Posted: 24 Jan 2019, 09:23
by mast4rwang
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?

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

Posted: 24 Jan 2019, 10:02
by nnnik
A fraction of how the other solution is blocking.

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

Posted: 24 Jan 2019, 11:56
by evilC
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

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

Posted: 24 Jan 2019, 14:38
by mast4rwang
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

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

Posted: 30 Jan 2019, 20:52
by YaBoi011011
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?

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

Posted: 30 Jan 2019, 21:08
by YaBoi011011
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

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

Posted: 31 Jan 2019, 05:38
by evilC
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