AutoHotKey loop and key pressed - autohotkey

got a small test script
o::
Suspend
{
Send {JK} ;
}
Pause,,1
Return
where can i ass a loop so it loops JK and the hotkey o still works?
i tried to put loop in a few places like
Loop,
o::
Suspend
{
Send {JK} ;
}
Pause,,1
Return
it just didnt work wherever i put the Loop
Or is there another way that could possibly be done doing it not the way I tried? Kinda new to this so hopefully I could get an answer

So if I understand correct, you want the script keep sending JK when you pressed o once and the o still works? If so, this should work. You can add sleep after send if it's too fast. You just need to add ~ before hotkey so it's not blocking the hotkey itself. And for looping JK, Loop should be inside the hotkey function.
~o::
Loop,
{
Suspend
Send, {JK}
Pause,,1
}
Return

Related

How can I use autohotkey to stop WASD movement while holding down the left mouse button?

I'm interested in disabling the w,a,s, & d keys while holding down the left mouse button.
(Games such as cs:go and valorant penalize shooting while moving, so I'd like to preclude that situation entirely).
I just learned about autohotkey, so I'm sorry if I offend someone with this attempt at code(which obviously doesn't work):
while (GetKeyState("LButton", "P"))
{
w::return
a::return
s::return
d::return
}
Thanks, much appreciated!
I just want to add in the solution that #Spyre hinted at. The script does indeed become much smaller when you use the #If directive, and when the if statement fails, the hotkey doesn't fire, so it doesn't add to your overall hotkeys per interval. Here is my version of the script:
#If GetKeyState("LButton", "P")
w::
a::
s::
d::
Return
Use #If (docs):
#If, GetKeyState("LButton")
w::
a::
s::
d::return
#If
And if #If were to cause you trouble (like warned about in the documentation) (it's not going to happen if your script is this small and simple), you'd want to do turn on and off the hotkeys with the Hotkey command.
For example:
~LButton::ConsumeASDW("On") ;press down
LButton Up::ConsumeASDW("Off") ;release
ConsumeASDW(OnOff)
{
for each, key in StrSplit("asdw")
Hotkey, % key, Consumer, % OnOff
}
Consumer()
{
Return
}
You've got the right idea, but what you currently have will be auto-executed at the beginning of the script, and after one run through of checking whether or not the LMB is held down, the script will stop doing anything.
My approach, using the $ modifier with hotkeys to make sure the hotkey doesn't recursively trigger itself.
$w::
if (GetKeyState("LButton", "P"))
return
Send w
return
$a::
if (GetKeyState("LButton", "P"))
return
Send a
return
$s::
if (GetKeyState("LButton", "P"))
return
Send s
return
$d::
if (GetKeyState("LButton", "P"))
return
Send d
return
There might be some more efficient way of declaring the condition of the hotkeys using the #If directive, but this should the job that you need it to.

My macro wont run more than once?

I have a simple macro, since i am very new to it. Literally started today. But i run this macro, and it runs once and stops. Why is that? Here it is:
q::
Send asdq
Esc::ExitApp
return
If someone could help me, I would really appreciate it.
Each hotkey you assign, that isn't a single line, requires a Return.
Since you have a definition of a Hotkey inside another, your second hotkey esc::exitapp is being executed when you press q and exiting your script.
Try:
q::Send, asdq
Esc::ExitApp
or:
q::
Send, asdq
Return
Esc::ExitApp
Edit:
q::
Loop
Send, asdq
Return
Esc:: ExitApp

Autohotkey. Hold two buttons and tap another to increase volume

I got stuck building an ahk shortcut script to increase / decrease Volume. The idea was to hold down LAlt+LShift and tap F12 to increase one step per tap.
The order in which LAlt and LShift are pressed shouldn't matter.
I came up with this so far:
!+::
While (GetKeyState("LShift","P")) and (GetKeyState("LAlt","P"))
{
F12::Send {Volume_Up}
}
Return
But somehow it increases the volume on holding LAlt and taping F12. LShift gets igronred..
What's wrong with that...
This
F12::Send {Volume_Up}
isn't a command, it's a hotkey assignment. You cannot use it within executable context. It is actually the short form for:
F12::
send {volume_up}
return
You wouldn't wanna have a return somewhere in between the lines which should be executed, would you.
As can be read in the documentation, you can only combine two Hotkeys for an action easily, like a & b::msgbox, you pressed a and b. E.g. for a,b AND c, you'd need some workaround like the crossed out, old answer below.
BUT you can add as many modifiers to your hotkey as you want. Modifiers are ! alt, + shift, # win and so on (please have a look # http://ahkscript.org/docs/Hotkeys.htm#Symbols).
So you can simply use
<!+F12::send {volume_up}
-
So, your aim is simply to have volume_up be fired when three Hotkeys are being pressed. You can achieve it like this:
#if getKeyState("LShift", "P")
*<!F12::send {volume_up}
#if
or
*<!F12::
if(getKeyState("LShift","P"))
send {volume_up}
return
For the meaning of * and < and other possible modifiers, see http://ahkscript.org/docs/Hotkeys.htm#Symbols
Your approach wasn't too bad. It would have worked if you had used the Hotkey command instead of an actual hotkey assignment. Still that would have been unneeded work

Simple keypress script with loop in Autohotkey

Whenever you press w you get into a loop that press e around every 10 seconds. Another button has to be pressed to get out of it again at any moment (and making it possible to start over again). This is what I have so far:
w::
Loop
{
Send, e
Random, SleepAmount, 9000, 10000
Sleep, %SleepAmount%
x::Break
}
Return
I don't understand why it is not working yet. It presses e once and doesn't do anything anymore after that.
x::Break
is the short form for
x::
break
return
and therefore terminates the current subroutine. Never define a hotkey within any other execution bodies. Instead, define the x-hotkey outside the w hotkey and make it stop the loop.
Example using goTo (note that goSub is different for the latter will not terminate the subroutine):
w::
Loop {
send e
Random, SleepAmount, 9000, 10000
Sleep, %SleepAmount%
}
after_loop:
return
x::
goTo after_loop
return
; or, more compact:
; x::goto after_loop
Since gotos are pretty bad programming style, you might consider using a timer (instead of the loop). But to be honest, it's not worth it because your sleep amount is not fix.

hotkeys does not work when send is in loop

Assume this code:
Loop
{
if enabled
Send, /
}
m::
enabled := !enabled
Return
I want to toggle sending / to a Notepad for example. But if I run this code by pressing M on keyboard, then pressing the M key again does not disable sending.
Looks like the send command in the Loop cause this issue since Ive tried using msgbox which does not disable the m key.
How can I make this code to work? (SendInput and Play does not work too)
It's because your loop is blocking any other execution. Unless that loop is the only thing in your script, you generally want to avoid using loops and use timers instead.
Timers don't block further execution but act more like their own thread. Here's an example using a timer:
slashTimerActive := 0
m::
if (!slashTimerActive)
SetTimer, SendSlash, 100 ; Call the sub every 100ms
else
SetTimer, SendSlash, Off
slashTimerActive := !slashTimerActive ; Flip the variable
return
; Subroutine
SendSlash:
SendInput, /
return