The issue seems to be that if you hold down a key it seems to be spamming the command instead of sending it once. For example I would like the command
k::Send ^ n
to send a single ctrl + n if I hold the k key down, but it seems to spam it infinitely. How do I make it happen only once?
$k::
Send ^n
KeyWait, k ; wait for k to be released
return
or
$k up:: Send ^n ; if you want to send a command by releasing a key
Press k longer than 0,5 seconds to send ^n:
$k::
KeyWait, k, T0.5
If (!ErrorLevel)
Send k
else
{
Send ^n
KeyWait, k
}
return
Whats wrong with
k::
if(getKeyState("k","P"))
return
send ^n
return
This would check if k is pressed down already physically, and if so, not do anything.
Related
New to Auto Hotkey. I’m looking to create a hotkey to press and hold Control, then press and hold Alt, then press “W”, then let go of all 3 and do the same after 30 seconds.
I tried this but unsure if it’s right. Thanks!
#SingleInstance, force
#MaxThreadsPerHotkey 2
F10::
Toggle := !Toggle
while Toggle
{
Send, {Ctrl}
Send, {Alt}
Send, {W}
Sleep, 30000 ;
}
Return
This should work:
#SingleInstance, force
F10::
Toggle := !Toggle
if (Toggle)
{
gosub, sub
SetTimer sub, 30000
}
else{
SetTimer sub, Off
}
Return
sub:
Send ^!w
return
Notes:
When a sleep command is used, the program is unable to detect hotkeys being pressed. Instead of using multiple threads, it would be better to implement a SetTimer/ Subroutine system.
In order to send Ctrl+Alt+W, just use Send ^!w. (^ means Control, ! means Alt, and and w means w; for more info, see modifiers.
The script should to the following:
Press 'C': Start/Stop script
Left Mouse Button: Start/Stop the loop
Inside the loop: While holding down the Left Mouse Button, the left mouse button is repeated till I lift my finger of it.
The mouse goes back to the center of the screen after every click.
Alternative the mouse is moved X pixel down after each click and my script is very slow.
It goes click .. click .. click instead of ClickClickClick :(.
I changed it to this now, but the Left Mouse Button is always activated even when not holding it down, I can't stop/start the script with C too.
HotKey, ~$*LButton, myLButtonAction ; Activate the hotkey by default
return
~c:: ; configure a Hotkey: c will enable / disable your LButton actions
HotKey, ~$*LButton, toggle ; ON / OFF
return
myLButtonAction: ;cnote: this is NOT a hotkey, it's a label
Loop
{
Click
Sleep 7,516 ;your loop actions (see question code)
}
return ; don't forget your returns at the end of a label / hotkey
Looks like you need to use the Hotkey command.
x := (A_ScreenWidth // 2)
y := (A_ScreenHeight // 2)
HotKey, ~$*LButton, myLButtonAction ; Activate the hotkey by default
setMouseDelay, 0
setKeyDelay, 0
return
~c:: ; configure a Hotkey: c will enable / disable your LButton actions
HotKey, ~$*LButton, toggle ; ON / OFF
return
myLButtonAction: ; note: this is NOT a hotkey, it's a label
Loop ;loop the script until broken
{ ;loop start
GetKeyState, var, LButton, P ;Get the state of Lbutton
If var = U ;has it been released?
Break ;its been released so break the loop
;Send {LButton} ;It hasnt been released so send another Click
Click %x%, %y%
Sleep 100 ;time between presses, after sleep return to the top of the loop
} ;loop end
return ; don't forget your returns at the end of a label / hotkey
my script is very slow. It goes click .. click .. click instead of ClickClickClick :(
Include setMouseDelay, 0 into your auto-execution section. I already did this in the code example above.
since I have to give away my macro keyboard I found autohotkey to be reliable. Sadly I didn't really find out how to make continuous macros..
what I mean is: (pseudo code)
^!c::
while ^!c is not pressed again -> send keystrokes c
spamm infinite c keystrokes until I press the combination above again
How do I approach this?
toggle = 0 ; timer is off because toggle isn't yet initialized
return
^!c:: ; toggle timer
if toggle := !toggle
SetTimer, Send_c, 0
else
SetTimer, Send_c, off
return
Send_c:
Send c
Sleep, 300
return
I am trying to build following gesture:
Click And Hold Right Mouse Button, Click Left mouse button => fire browser back key
RButton & LButton Up::
Send {Browser_Back}
return
~RButton::return
The problem is I want to consume the last "right button up" when release the right button after this hotkey was pressed. Effectively I dont want to see the context menu poppong up.
Any Help?
Edit: It would be nice if we can preserve right drag.
I'm assuming you don't want to block the right button menu at all times.
rbutton & lbutton::Send, {Browser_Back}
rbutton::click r
Otherwise exclude the second line.
Update: Since you have now specified that you use "right-drag"
here is another idea (note: I don't use right-drag so I can't confirm anything):
rbutton::
Keywait, rbutton, T0.5
If (ErrorLevel) {
Click r d
Keywait, rbutton
Click r u
} Return
lbutton::
if GetKeyState("rbutton", "P")
Send, {Browser_Back}
Else {
Click d
Keywait, lbutton
Click u
} Return
You will have to hold rbutton and left click then release rbutton within 0.5seconds, or raise the time.
The basic version simply won't work as far as I know. This is because using & will make rbutton only fire upon release.
If this still doesn't work you could try something even more complicated: link
Update: I just thought of another variation:
Lbutton::
if GetKeyState("rbutton", "P")
Send, {Browser_Back}
Else {
Click d
Keywait, lbutton
Click u
} Return
rbutton up::
If (a_priorhotkey != "Lbutton" or a_timeSincePriorHotkey > 500)
Click r
Return
I'm trying to write a script that has a loop in which the upper arrow key is pressed every two seconds. The loop must be activated when I press the spacebar and deactivated when I press it again. I'm now using this.
$Space::
if GetKeyState("Space", "P")
{
Loop
{
Sleep 2000
Send {Up}
if GetKeyState("Space", "P")
{
return
}
}
}
For some reason, the if condition inside the loop doesn't work, i.e. I can't get out of the loop. I hope anyone can help me out...
You wouldn't need the first if GetKeyState("Space", "P")
and you would need to be holding space when the loop got to the second one
for it to break; and you would need to replace the return with break.
However I agree with Gary, although I would write it like this:
; (on:=!on) reverses the value of variable 'on'
; the first press of space reverses on's value (nothing) to something (1)
; the second press reverses on's value from (1) to (0)
; when (on = 1) delay will be set to 2000, and Off when (on = 0)
space::SetTimer, Action, % (on:=!on) ? ("2000") : ("Off")
Action:
Send, {up}
Return
% starts an expression.
From http://l.autohotkey.net/docs/Variables.htm
?:
Ternary operator
This operator is a shorthand replacement for the if-else statement.
It evaluates the condition on its left side to determine
which of its two branches will become the final result.
For example, var := x>y ? 2 : 3 stores 2 in Var if x is greater than y; otherwise it stores 3.
How about using SetTimer?
; Create timer.
SetTimer, SendUp, 2000
; Set timer to 'Off' at start of script.
SetTimer, SendUp, Off
TimerEnabled := False
; When Space is pressed toggle the state of the timer.
$Space::
If TimerEnabled
{
SetTimer, SendUp, Off
TimerEnabled := False
}
Else
{
SetTimer, SendUp, On
TimerEnabled := True
}
; Label called by timer to send {Up} key.
SendUp:
Send, {Up}
return