How to toggle a set of keybinds on and off? - toggle

I am trying to set up a group of keybinds that I can toggle on and off with a single button press but haven't been able to find any examples anywhere.
I want ^NumpadSub to toggle these different keybinds to turn them on and off when I press ^NumpadSub.
q::w
z::s
w::up
s::down
Can anyone help on how I would set up the code to do so?

When these are the ONLY ones, you could add one more hotkey:
^NumpadSub::Suspend
This will suspend ALL hotkeys (except the one that is used for toggling suspend on/off)
Otherwise you would have to use the actual hotkey function (http://www.autohotkey.com/docs/commands/Hotkey.htm) which allows you to turn hotkeys on/off, but the hotkey function refers to labels: (go to addresses).
If you want to ONLY have these keys act a certain way when you use ONE particular application (Game), you can use the #IfWinActive command.
e.g.
SetTitleMatchMode, 2
#IfWinActive, Notepad ; Start of Notepad specific keys.
a::Send, Haha
b::SoundBeep, 500, 500
#IfWinActive ; End of Notepad specific keys.
In that situation, Check out if this works for you! I added $ signs in front of w and s because hitting q and z would trigger the execution of w and s
Hotkey, q , MyQ, On
Hotkey, z , MyZ, On
Hotkey, $w , MyW, On
Hotkey, $s , MyS, On
Return
^NumpadSub::
KeyToggle:=!KeyToggle
Hotkey, q , % (KeyToggle ? "Off": "On")
Hotkey, z , % (KeyToggle ? "Off": "On")
Hotkey, $w , % (KeyToggle ? "Off": "On")
Hotkey, $s , % (KeyToggle ? "Off": "On")
Return
MyQ:
SendInput, w
Return
MyZ:
SendInput, s
Return
MyW:
SendInput, {Up}
Return
MyS:
SendInput, {Down}
Return

Related

Autohotkey: Define a hotkey and passthrough it to system dynamically, how to?

I'm facing a somewhat hard question. Look at this script:
; Using Autohotkey 1.1.36.2
F2::
send_f2_withcond()
{
if(WinExist("ahk_class Notepad"))
{
ControlSend Edit1, % A_Now "`r", % "ahk_class Notepad"
}
else
{
; I hope F2 can do its original action. How to?
Send {$F2} ; ??? No effect!
}
}
My purpose:
If there is Notepad running, F2 will send some text to Notepad.
If Notepad is not running, I hope F2 can do it original action, for example, pressing F2 in an Explorer window will start renaming current highlighted file.
Writing Send {F2} is not correct, because it will trigger my own F2:: ... action recursively.
The doc says adding a $ prefix will suppress recursive calling, BUT, Send {$F2} takes no effect(as if I totally omit this Send), the current active application receives only F2's WM_KEYUP, no WM_KEYDOWN.
The $ prefix is used only in hotkey definitions. It forces the keyboard hook to be used, which is designed to filter out keys sent by AutoHotkey scripts.
$F2:: send_f2_withcond()
send_f2_withcond() {
if WinExist("ahk_class Notepad")
ControlSend, Edit1, % A_Now "`r", % "ahk_class Notepad"
else
Send {F2}
}
You can greatly simplify this script by using #IfWinExist.
#IfWinExist, ahk_class Notepad
F2::ControlSend Edit1, % A_Now "`r", % "ahk_class Notepad"
#IfWinExist

Release of Ctrl and Shift doesn't work properly with Caps Lock

I try to do a shortcut of Ctrl+f+j so that the Ctrl+j will make j a left arrow, and the combination of f will make it a Ctrl (d should work the same with shift), so Ctrl+f+j will be considered as Ctrl+Left Arrow.
I've succeeded in making it work, but after I release the keys, f and d stuck and I can not return to normal mode.
I have the following code:
CapsLock & j::
{
Send, {blind}{Left}
return
f::Ctrl
d::Shift
return
}
CapsLock & l::
{
Send, {blind}{Right}
return
f::Ctrl
d::Shift
return
}
CapsLock up::
{
Send {Ctrl Up}
Send {Shift Up}
return
}
this works well until I release the l key because the d and f keys can not be used afterward. Any ideas why? I just can't use them regularly They keep function as Ctrl and Shift
The solution was to separate the combinations. Turns out ahk does not support nested hotkeys, and doing that messes the releases of the keys. The following code solved my problem.
CapsLock & l::Send, {blind}{Right}
CapsLock & j::Send, {blind}{Left}
CapsLock & f::Ctrl
CapsLock & d::Shift

How to map semi-colon then Esc to something other in AutoHotkey?

How to set up AutoHotkey so that when I press semi-colon then Esc ;esc in order, it will instead do something other?
:?*:;Esc::
msgbox, hello world
;; do something
;; Send, {BACKSPACE} ;; remove the ; at last
return
I think you might not be able to do it with hotstrings, but instead with a regular hotkey. Also, I think you'll need to change the comment flag to something else that isn't a semicolon. Here's my attempt:
#CommentFlag //
~;::
KeyWait , Esc , DT2
If !ErrorLevel
{
Send , {backspace}
msgbox
}
Return

AutoHotkey - Detect double press of AltGr

I want to detect double press on AltGr.
According to documentation:
; Example #4: Detects when a key has been double-pressed (similar to double-click).
; KeyWait is used to stop the keyboard's auto-repeat feature from creating an unwanted
; double-press when you hold down the RControl key to modify another key. It does this by
; keeping the hotkey's thread running, which blocks the auto-repeats by relying upon
; #MaxThreadsPerHotkey being at its default setting of 1.
; Note: There is a more elaborate script to distinguish between single, double, and
; triple-presses at the bottom of the SetTimer page.
~RControl::
if (A_PriorHotkey <> "~RControl" or A_TimeSincePriorHotkey > 400)
{
; Too much time between presses, so this isn't a double-press.
KeyWait, RControl
return
}
MsgBox You double-pressed the right control key.
return
AltGr is actually a combination of LControl & RAlt. So, for AltGr, script should be something like this:
~LControl & RAlt::
if (A_PriorHotkey <> "~LControl & RAlt" or A_TimeSincePriorHotkey > 400)
{
click
KeyWait, LControl & RAlt
return
}
click 2
return
But when I try to load this script, AutoHotkey gives an error:
Maybe there is a way to make an alias for key combinations.
As mentioned in the comments, KeyWait can only wait on one key (not hotkey) at a time. You only need to wait for RAlt to be released, not the combination of LCtrl and RAlt.
This works:
~LControl & RAlt::
if (A_PriorHotkey <> "~LControl & RAlt" or A_TimeSincePriorHotkey > 400)
{
KeyWait, RAlt
return
}
MsgBox Double-click
return
However, in this case KeyWait is only being used (in combination with the default #MaxThreadsPerHotkey setting of 1) to prevent key-repeat from activating the hotkey. You can remove KeyWait and it will still detect double-presses; but it will also activate if you hold AltGr down until it auto-repeats.
Note that in your case, double-pressing the hotkey would click three times: once on the first press and an additional two times on the second press.
If you just want to use AltGr as a mouse button and allow double-click, all you need is <^RAlt::Click.
If you want to perform two different actions depending on whether it is a single or double click, you must delay the response to the first click until you know whether there's a second click. For example:
<^RAlt::
KeyWait RAlt
KeyWait RAlt, D T0.4
if ErrorLevel
MsgBox Single
else
MsgBox Double
return

Could someone explain this autohotkey script to me?

It's supposed to let me turn a toggle a run button on and off in a game (instead of having to hold it down). It works, but I'd like to know how.
$w:: Gosub, AutorunToggleME2
~s:: Gosub, AutoRunOffME2
AutorunToggleME2:
toggle := !toggle
Send % "{w " . ((Toggle) ? ("down") : ("up")) . "}"
return
AutoRunOffME1:
toggle = ; Off
Send {w up}
return
Specifically, I'd like what the following lines do:
Send % "{w " . ((Toggle) ? ("down") : ("up")) . "}"
Send {w up}
The code is pretending to hold down w. The basic Send syntax is explained here.
To hold down or release a key: Enclose in braces the name of the key
followed by the word Down or Up. For example:
Send {b down}{b up}
Send {TAB down}{TAB up}
Send {Up down} ; Press down the up-arrow key.
Sleep 1000 ; Keep it down for one second.
Send {Up up} ; Release the up-arrow key.
So this line:
Send {w up}
Clearly is releasing w.
The other line is more complicated:
Send % "{w " . ((Toggle) ? ("down") : ("up")) . "}"
You can find explanations of the relevant syntax here.
Basically:
% says that the following text is an expression.
The . is a string-concatenation operator.
This part ((Toggle) ? ("down") : ("up")) is the conditional operator (a.k.a ternary operator). It's shorthand for an if/else statement. In this case, when Toggle is true, it returns "down", otherwise it returns "up".
This works out to either Send {w down} or Send {w up} depending on the value of Toggle (true or false)