Key Hold to Run script question

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Key Hold to Run script question

08 Apr 2024, 21:36

I want to create a script that only runs when i hold down a key or the mouse button and it stops when i let go. Is there a way to create such a script? Basically when i run the script, nothing happens until i hold down the specified key and when i let go, the script stops. then when i push the key again it runs the script back from the beginning again. How can i create such a script?
awkwrd
Posts: 11
Joined: 26 Feb 2023, 21:04

Re: Key Hold to Run script question

09 Apr 2024, 01:34

My suggestion is using SetTimer and GetKeyState.
Here's an example. Save this code in ahk file extension and type the path to the ahk file in the "Path_to_this_ahk_file" variable.
When you hold down Numpad8 key, it'll show a Tooltip with a number and count up to 5 while Numpad8 is held down. It stops and resets whenever you let go of Numpad8.
I couldn't find a direct way to use SetTimer to stop the original function though, so I used this kludge of running 2 instances. Letting go of Numpad8 runs a 2nd instance and then closes the original instance (which simulates "when i push the key again it runs the script back from the beginning again")
If your script is simple and you are able to use a While loop, then just use a While loop instead of my funky WinClose A_ScriptHwnd technique.
If anyone has any improvements or critiques then please let me know.

Code: Select all

Path_to_this_ahk_file := ""		;type the path to the ahk file here!
#SingleInstance Off		;enables running 2 instances

Numpad8::
{
	Global ID_of_this_instance := A_ScriptHwnd
	SetTimer CheckIfKeyIsHeldDown, 20		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function
	Tooltip 1
	Sleep 1000
	Tooltip 2
	Sleep 1000
	Tooltip 3
	Sleep 1000
	Tooltip 4
	Sleep 1000
	Tooltip 5
}

CheckIfKeyIsHeldDown()
{
	If not GetKeyState("Numpad8")		;if you let go of Numpad8, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

09 Apr 2024, 07:42

awkwrd wrote:
09 Apr 2024, 01:34
My suggestion is using SetTimer and GetKeyState.
Here's an example. Save this code in ahk file extension and type the path to the ahk file in the "Path_to_this_ahk_file" variable.
When you hold down Numpad8 key, it'll show a Tooltip with a number and count up to 5 while Numpad8 is held down. It stops and resets whenever you let go of Numpad8.
I couldn't find a direct way to use SetTimer to stop the original function though, so I used this kludge of running 2 instances. Letting go of Numpad8 runs a 2nd instance and then closes the original instance (which simulates "when i push the key again it runs the script back from the beginning again")
If your script is simple and you are able to use a While loop, then just use a While loop instead of my funky WinClose A_ScriptHwnd technique.
If anyone has any improvements or critiques then please let me know.

Code: Select all

Path_to_this_ahk_file := ""		;type the path to the ahk file here!
#SingleInstance Off		;enables running 2 instances

Numpad8::
{
	Global ID_of_this_instance := A_ScriptHwnd
	SetTimer CheckIfKeyIsHeldDown, 20		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function
	Tooltip 1
	Sleep 1000
	Tooltip 2
	Sleep 1000
	Tooltip 3
	Sleep 1000
	Tooltip 4
	Sleep 1000
	Tooltip 5
}

CheckIfKeyIsHeldDown()
{
	If not GetKeyState("Numpad8")		;if you let go of Numpad8, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}
Thank you very much for your response and the example. There seems to be an error though, the script counts only up to 5 and repeats and when i let go of the Numpad, i get this error.
image.png
image.png (17.76 KiB) Viewed 225 times
I pasted the path to the file at the top just like the code says to do so not sure why i am getting the error.
User avatar
boiler
Posts: 16996
Joined: 21 Dec 2014, 02:44

Re: Key Hold to Run script question

09 Apr 2024, 08:24

@boat_58 — The path to the file needs to include the script file itself, not just the folder in which it resides.
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

09 Apr 2024, 09:32

boiler wrote:
09 Apr 2024, 08:24
@boat_58 — The path to the file needs to include the script file itself, not just the folder in which it resides.
Thank you. I forgot to add the .ahk extension. It is now working as intended.

Instead of using Numpad8, how can i make it so it uses mouse button 4 or 5? I have tried Xbutton[1-5] just to test it and its not working.

Thanks
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

09 Apr 2024, 09:46

awkwrd wrote:
09 Apr 2024, 01:34
My suggestion is using SetTimer and GetKeyState.
Here's an example. Save this code in ahk file extension and type the path to the ahk file in the "Path_to_this_ahk_file" variable.
When you hold down Numpad8 key, it'll show a Tooltip with a number and count up to 5 while Numpad8 is held down. It stops and resets whenever you let go of Numpad8.
I couldn't find a direct way to use SetTimer to stop the original function though, so I used this kludge of running 2 instances. Letting go of Numpad8 runs a 2nd instance and then closes the original instance (which simulates "when i push the key again it runs the script back from the beginning again")
If your script is simple and you are able to use a While loop, then just use a While loop instead of my funky WinClose A_ScriptHwnd technique.
If anyone has any improvements or critiques then please let me know.

Code: Select all

Path_to_this_ahk_file := ""		;type the path to the ahk file here!
#SingleInstance Off		;enables running 2 instances

Numpad8::
{
	Global ID_of_this_instance := A_ScriptHwnd
	SetTimer CheckIfKeyIsHeldDown, 20		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function
	Tooltip 1
	Sleep 1000
	Tooltip 2
	Sleep 1000
	Tooltip 3
	Sleep 1000
	Tooltip 4
	Sleep 1000
	Tooltip 5
}

CheckIfKeyIsHeldDown()
{
	If not GetKeyState("Numpad8")		;if you let go of Numpad8, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}
Does this script only work with Numpad8? I am trying to switch it to work with Mouse button 4 or 5 but its not working. I decided to do some testing and try Numpad2 and other keys but it seems to not work with anything else other than Numpad8. When i try another key, it just runs tooltip 1 over and over really fast and thats it.
User avatar
boiler
Posts: 16996
Joined: 21 Dec 2014, 02:44

Re: Key Hold to Run script question

09 Apr 2024, 11:12

Note that the function CheckIfKeyIsHeldDown also has Numpad8 hardcoded to it, so it would need to be changed there as well. It would be better if it automatically checked the hotkey (assuming it’s not a key combination) by binding it as a parameter like this:

Code: Select all

SetTimer CheckIfKeyIsHeldDown.Bind(A_ThisHotkey), 20
…and changing the function to this:

Code: Select all

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key)		;if you let go of the key, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}

Then you should be able to change to another hotkey in just the one place.
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

09 Apr 2024, 12:41

boiler wrote:
09 Apr 2024, 11:12
Note that the function CheckIfKeyIsHeldDown also has Numpad8 hardcoded to it, so it would need to be changed there as well. It would be better if it automatically checked the hotkey (assuming it’s not a key combination) by binding it as a parameter like this:

Code: Select all

SetTimer CheckIfKeyIsHeldDown.Bind(A_ThisHotkey), 20
…and changing the function to this:

Code: Select all

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key)		;if you let go of the key, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}

Then you should be able to change to another hotkey in just the one place.
Thank you so much. It works with every hotkey now except mouse buttons. Is there a reason why when i use Left/Right mouse clicks and Mouse Botton 4 or 5 it doesn't work? Ideally, i would love if it would work with mouse button 4 as it would make the activation of the code easier. I try XButton2 for the activation but it only activate the first line only and not the rest.
User avatar
boiler
Posts: 16996
Joined: 21 Dec 2014, 02:44

Re: Key Hold to Run script question

09 Apr 2024, 14:32

I'm not sure, but why are you running a second instance of the sript and killing another instead of just using Reload?
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

10 Apr 2024, 07:49

boiler wrote:
09 Apr 2024, 14:32
I'm not sure, but why are you running a second instance of the sript and killing another instead of just using Reload?
That was the code that was suggested by an earlier user trying to help. Can you show me how using "Reload" instead would look like with the below code that i have for testing? I am fairly new at this. I really appreciate all the feedback and help.

Code: Select all

#Requires AutoHotkey v2.0
Path_to_this_ahk_file := "C:\Users\Jeff\Desktop\test2.ahk"		;type the path to the ahk file here!
#SingleInstance Off		;enables running 2 instances

1::
{
	Global ID_of_this_instance := A_ScriptHwnd
	SetTimer CheckIfKeyIsHeldDown.Bind(A_ThisHotkey), 20		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function

;~ 		;********************************************************* Hammer Weapon		
		Send "t" ; 
		Sleep 800
		Send "g" ;
		Sleep 700
		Send "f" ;
		Sleep 700
		Send "3" ; 
		Sleep 700
		Send "{F3}" ; 
		Sleep 1100
		Send "4" ; 
		Sleep 1000
		Send "2" ;
		Sleep 750
}

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key)		;if you let go of the key, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}

Esc::ExitApp
User avatar
boiler
Posts: 16996
Joined: 21 Dec 2014, 02:44

Re: Key Hold to Run script question

10 Apr 2024, 07:55

Code: Select all

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key)		;if you let go of the key, then:
		Reload
}
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

10 Apr 2024, 12:13

boiler wrote:
10 Apr 2024, 07:55

Code: Select all

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key)		;if you let go of the key, then:
		Reload
}
Is the "Reload" suppose to generate multiple instances of the script when it is restarted from holding the key down long?
image.png
image.png (5.06 KiB) Viewed 146 times
Attachments
image.png
image.png (5.06 KiB) Viewed 146 times
User avatar
boiler
Posts: 16996
Joined: 21 Dec 2014, 02:44

Re: Key Hold to Run script question

10 Apr 2024, 13:04

It may be because you have #SingleInstance Off at the top of your script. Try removing that.
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

10 Apr 2024, 13:25

boiler wrote:
10 Apr 2024, 13:04
It may be because you have #SingleInstance Off at the top of your script. Try removing that.
I used the below script to test. I removed the SingleInstance from the top and it was still showing multiple instances of the script based on how many times it re-ran while i had the button pushed down. When i try to do it again, all those instances try to go at the same time.

Code: Select all

#Requires AutoHotkey v2.0
Path_to_this_ahk_file := "C:\Users\Jeff\Desktop\test.ahk"		;type the path to the ahk file here!


1::
{
	Global ID_of_this_instance := A_ScriptHwnd
	SetTimer CheckIfKeyIsHeldDown.Bind(A_ThisHotkey), 20		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function
	Tooltip 1
	Sleep 1000
	Tooltip 2
	Sleep 1000
	Tooltip 3
	Sleep 1000
	Tooltip 4
	Sleep 1000
	Tooltip 5
}

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key)		;if you let go of the key, then:
		Reload
}
Esc::ExitApp
image.png
image.png (9.39 KiB) Viewed 139 times
User avatar
boiler
Posts: 16996
Joined: 21 Dec 2014, 02:44

Re: Key Hold to Run script question

10 Apr 2024, 14:18

Try putting #SingleInstance Force or #SingleInstance Ignore instead.
boat_58
Posts: 12
Joined: 08 Apr 2024, 21:33

Re: Key Hold to Run script question

10 Apr 2024, 15:15

boiler wrote:
10 Apr 2024, 14:18
Try putting #SingleInstance Force or #SingleInstance Ignore instead.
They did not work. It still creates multiple instances. I have tried different test scrips and its the same thing.
awkwrd
Posts: 11
Joined: 26 Feb 2023, 21:04

Re: Key Hold to Run script question

11 Apr 2024, 01:55

I suggested running a second instance, because at the time, I tried using Exit from the timer, but it didn't stop the original thread. I didn't think of trying Reload.

I just tried using Reload now and just like boat_58, I'm getting multiple instances. I tried:

- #SingleInstance Force
- #SingleInstance Ignore
- not including "#SingleInstance" in the script at all

all resulted in multiple instances anyway.

Also, I tested the script with XButton1 and XButton2, and they didn't work for me too.
boat_58's script that utilises 2 instances works with the "1" key though.
awkwrd
Posts: 11
Joined: 26 Feb 2023, 21:04

Re: Key Hold to Run script question

11 Apr 2024, 02:21

I managed to get both of the XButtons to work for me. Use the "P" mode in GetKeyState.

@boat_58 Try this, don't forget to change the path to ahk file.

Code: Select all

#Requires AutoHotkey v2.0
Path_to_this_ahk_file := ""		;type the path to the ahk file here!
#SingleInstance Off		;enables running 2 instances

XButton1::
{
	Global ID_of_this_instance := A_ScriptHwnd
	SetTimer CheckIfKeyIsHeldDown.Bind(A_ThisHotkey), 20		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function

;~ 		;********************************************************* Hammer Weapon		
		Send "t" ; 
		Sleep 800
		Send "g" ;
		Sleep 700
		Send "f" ;
		Sleep 700
		Send "3" ; 
		Sleep 700
		Send "{F3}" ; 
		Sleep 1100
		Send "4" ; 
		Sleep 1000
		Send "2" ;
		Sleep 750
}

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key, "P")		;if you let go of the key, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}

Esc::ExitApp
awkwrd
Posts: 11
Joined: 26 Feb 2023, 21:04

Re: Key Hold to Run script question

11 Apr 2024, 03:12

Thank you @boiler for showing how to bind a parameter to a Func Object.
(It's included in the AHK documentation, but I never knew how to use it until I could see an actual example, which boiler provided.)

@boat_58 I've improved the script by changing ID_of_this_instance from a Global variable to a Local variable.

Code: Select all

#Requires AutoHotkey v2.0
Path_to_this_ahk_file := ""		;type the path to the ahk file here!
#SingleInstance Off		;enables running 2 instances

XButton1::
{
	SetTimer CheckIfKeyIsHeldDown.Bind(A_ThisHotkey, A_ScriptHwnd), 20		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function

;~ 		;********************************************************* Hammer Weapon		
		Send "t" ; 
		Sleep 800
		Send "g" ;
		Sleep 700
		Send "f" ;
		Sleep 700
		Send "3" ; 
		Sleep 700
		Send "{F3}" ; 
		Sleep 1100
		Send "4" ; 
		Sleep 1000
		Send "2" ;
		Sleep 750
}

CheckIfKeyIsHeldDown(key, ID_of_this_instance)
{
	If not GetKeyState(key, "P")		;if you let go of the key, then:
	{
		Run Path_to_this_ahk_file		;run a 2nd instance of the same script
		WinClose ID_of_this_instance	;close the original 1st instance to stop it from continuing. I learnt this from:
		;https://www.autohotkey.com/docs/v2/Program.htm#main-window
			;"Closing this window with WinClose (even from another script) causes the script to exit"
	}
}

Esc::ExitApp
awkwrd
Posts: 11
Joined: 26 Feb 2023, 21:04

Re: Key Hold to Run script question

11 Apr 2024, 03:54

Reload wasn't working for us previously, because our SetTimer delay period was too short (only 20 ms).
If multiple instances of the script are started simultaneously, they may fail to detect each other or may all target the same previous instance. This would result in multiple instances of the script starting.
https://www.autohotkey.com/docs/v2/lib/_SingleInstance.htm#Limitations
#ItsNotABugItsAFeature

Reload works if we increase the SetTimer delay period (example 200 ms). You'll have to reckon with a slightly longer delay period though. If that's what you want then use this alternative code:

Code: Select all

#Requires AutoHotkey v2.0
Path_to_this_ahk_file := ""		;type the path to the ahk file here!

XButton1::
{
	SetTimer CheckIfKeyIsHeldDown.Bind(A_ThisHotkey), 200		;creates a timer which repeatedly runs my CheckIfKeyIsHeldDown() function every 200 ms

;~ 		;********************************************************* Hammer Weapon		
		Send "t" ; 
		Sleep 800
		Send "g" ;
		Sleep 700
		Send "f" ;
		Sleep 700
		Send "3" ; 
		Sleep 700
		Send "{F3}" ; 
		Sleep 1100
		Send "4" ; 
		Sleep 1000
		Send "2" ;
		Sleep 750
}

CheckIfKeyIsHeldDown(key)
{
	If not GetKeyState(key, "P")		;if you let go of the key, then:
		Reload
}

Esc::ExitApp

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Datrik, lukepker, mikeyww, sanmaodo, vmech and 58 guests