AHK blocked input - autohotkey

So I am making my script
toggl:=false
while(1){
if(toggl){
Send,E
}
Sleep, 150
}
!r::
toggl:=!toggl
return
!y::ExitApp,101
Problem is that while the loop is running, I can not cancel it because it blocks !y, so I had to restart computer. So any help with this would be nice.

Set #MaxThreads 2 to allow each hotkey to run twice, OR:
Use SetTimer to allow the hotkey to end and continue your loop in a "Pseudo-Thread".
toggle := 0
F12::
toggle := !toggle
if (toggle){
SetTimer, DoLoop, -100
}
return
DoLoop:
Loop {
if (!toggle){
break
}
; [Do your stuff here]
}
return

Related

A continuous while loop with actions toggled on/off by a hotkey, separate from the main body. How do I approach this?

I need to have
while (true) {
if (toggle) { ;(toggle is simply set on/off with a hotkey)
...stuff...
Sleep, 250
}
}
running independently separate from the main "thread", which in this case is stuck in a RunWait
prev_volume := 20
SoundGet, prev_volume
if (prev_volume <= 32) {
SoundSet, 26
}
RunWait, some game
SoundSet prev_volume
ExitApp
Not sure how to approach this
Any help is appreciated, thanks in advance.
So to use the command SetTimer in this instance:
SetTimer, ToggleThingy, On ; defaults to 250 ms
toggle := false
prev_volume := 20
SoundGet, prev_volume
if (prev_volume <= 32) {
SoundSet, 26
}
RunWait, some game
SoundSet prev_volume
ExitApp
{hotkey here}::
toggle := !toggle
Return
ToggleThingy:
if (toggle) { ;(toggle is simply set on/off with a hotkey)
...stuff...
; Sleep, 250 ; not needed because timer already runs every 250 ms
}
}
Return ; needed to end the subroutine.

AHK, not working as expected

trying to make a toggle-able loop, seems to be not sending e at all, help please?
myvar := false
k::
myvar := true ? false : true
return
while (myvar)
{
Send, e
Sleep 100
}
Here is my suggestion:
k::SetTimer, SendLetterE, % (Toggle:=!Toggle) ? 100 : "Off"
SendLetterE() {
Send, e
}
You can assign another key to pause / resume. In this case k will toggle and F12 will run indefinitely (so just use k to toggle).
k::
Hotkey, F12, toggle
return
F12::
while(true)
{
Send, e
Sleep 100
}
Could also try Loop instead of while(true)
k::
pause, toggle
F12::
Loop,
{
Send e
Sleep, 100
}
return
referenced from AutoHotkey forum.

Can someone help me with this AHK Script

I want this Autohotkey script to press the spacebar automatically with a toggle option so i dont have to hold the spacebar all the time. The toggle key should be the middle mouse button. Could you please write it correctly for me? Because the toggle part I found doesn't seem to work. Thanks in advance CptPrice :D
Main script:
*~$Space::
Sleep 100
Loop
{
GetKeyState, SpaceState, Space, P
If SpaceState = U
break
Sleep 5
Send, {Blind}{Space}
}
Toggle-part:
#MaxThreadsPerHotkey 2
MButton::
if (toggle := !toggle) {
; on
} else {
; off
}
return
toggle := false
return
MButton:: toggle := !toggle
#If toggle
#MaxThreadsPerHotkey 2
*~$Space::
Sleep 100
Loop
{
Sleep 5
Send, {Blind}{Space}
if (!toggle) ; Press MButton to break
break
}
return
#If

How do I condense multiple similar hotkeys into one in AutoHotkey?

I'm trying to create hotkeys to simulate input buffering in an online game I'm playing which doesn't natively support input buffering, meaning mashing a spell key so that it goes off after the previous spell is finished casting is the best method to manually do.
With the help of a hotkey I can loop the key press with minimal delay by holding down my key so that it sends the instant I'm done casting the previous spell.
However creating multiple hotkeys for each button I have bound on my keyboard to a spell seems tedious and I'm not sure how to condense these hotkeys into one using an array of defined keys (ie. 1 through 6, and F1 through F6)
An example snippet of my code so far with only 3 keys taken into account:
$5::
{
Loop
{
Loop, 5
{
Send, 5
Sleep, 1
}
GetKeyState, state, 5
if state = U
break
}
return
}
$2::
{
Loop
{
Loop, 5
{
Send, 2
Sleep, 1
}
GetKeyState, state, 2
if state = U
break
}
return
}
$F2::
{
Loop
{
Loop, 5
{
Send, {F2}
Sleep, 1
}
GetKeyState, state, F2
if state = U
break
}
return
}
I'm trying to condense it to something like this, if possible:
hotkeys := [5, 2, F2]
hotkeyCount := hotkeys.MaxIndex()
curKey := 1
Loop, hotkeyCount
{
hotkeyIndex := hotkeys[curKey]
$%hotkeyIndex%::
{
Loop
{
Loop, 5
{
Send, {%hotkeyIndex%}
Sleep, 1
}
GetKeyState, state, %hotkeyIndex%
if state = U
break
}
return
}
curKey := curKey + 1
}
Create a FIFO stack that will safe the preset actions and call them when they are ready.
Array functions contains the functions: Function_a, Function_b, Function_c, that are triggered with their respective hotkeys, a, b, c.
The hotkeys don't call the functions directly, but add their numerical index the to the stack stack.
The timer check, retrieves the numerical index from the stack, then the function from the array functions at that index is called. When the function returns, the next index is retrieved if there is any. Only one functions is running at a time.
SetBatchLines, -1
global stack := Object()
global stack_head = 0
global stack_tail = 0
global functions := [Func("Function_a"),Func("Function_b"),Func("Function_c")]
SetTimer, check , 25
return
check:
if( stack_head > stack_tail )
{
i := stack[stack_tail]
functions[i]()
stack_tail++
}
return
Function_a()
{
tooltip, Function_a running...
Sleep, 1000
tooltip,
return
}
Function_b()
{
tooltip, Function_b running...
Sleep, 1000
tooltip,
return
}
Function_c()
{
tooltip, Function_c running...
Sleep, 1000
return
}
a::
stack[stack_head] := 1
stack_head++
return
s::
stack[stack_head] := 2
stack_head++
return
d::
stack[stack_head] := 3
stack_head++
return
This enables concurrent running of the functions, that can do whatever you want, while at the same time hotkeys can add actions (functions indexes) to the stack, which will be called in order they were added one at a time.
I have edited you example to make it functional:
$a::
$s::
$d::
$1::
key := A_ThisHotkey
key :=Trim(key,"$")
Loop
{
Loop, 5
{
SendInput, %key%
Sleep, 1
}
state := GetKeyState(key , "P" )
if state = 0
{
break
}
}
return

Temporarily Pause Autofire loop on holding button

I wrote a script that sends autofire left clicks and can be triggered on and off. The script works. However, the problem is that holding the right mouse button does not work properly anymore because the left click keeps getting sent. So I want to change the script that it gets temporarily paused while I hold down the right mouse button.
How would I go about doing this? Here is my current code:
#MaxThreadsPerHotkey 3
#z::
#MaxThreadsPerHotkey 1
if keep_winz_running = y
{
keep_winz_running = n
return
}
; Otherwise:
keep_winz_running = y
Loop
{
GetKeyState, rbut, Rbutton
If rbut, = U
{
Loop,
{
MouseClick, left
Sleep, 50 ;This means the script will wait 1.5 secs
if keep_winz_running = n ; The user signaled the loop to stop.
break ; break out of the loop
}
Timers are the best!
sendToggle := false
#z::
if(!sendToggle) {
sendToggle := true
SetTimer, SendClick, 100
} else {
sendToggle := false
SetTimer, SendClick, Off
}
return
#If sendToggle
RButton::
SetTimer, SendClick, Off
KeyWait, RButton
SetTimer, SendClick, 100
return
SendClick:
Click
return
I find the send interval of 50 ms awfully fast, especially since you won't be able to actually reach 50 ms without reducing SetBatchLines and SetKeyDelay. If it really needs to be that fast, consider changing them.