Autohotkey Tutorial - hotkeys

Autohotkey Tutorial - hotkeys

posted in productivity on • last updated on

First we’ll cover the basic Autohotkey hotkey syntax. Which is arguably already pretty confusing for newcomers in and by itself.

But we don’t stop there as after adding more and more hotkeys, it will also become harder and harder to think of new key combinations that are somehow still memorable. There is only so much you can do with the # (Windows) key etc.

Time for some creative hotkey combinations! ‘Advanced Hotkeys’ covers code snippets on how to run different scripts on single, double or triple key presses as well as how to differentiate between long(ish) key presses or mouse clicks. And more…

Example

; Single line hotkey
^#D::MsgBox Pressed Control + Win + D (%A_ThisHotKey%)

; Control + Win + C: Multi line script
^#C::
Run, notepad.exe
WinWait, Untitled - Notepad, , 3
Send, Dear sir,{enter}{enter}
Return

Basic Syntax

Keyboard

Shorthand Full Desc
+ Shift  
^ Control or Ctrl  
# Win Windows
! Alt  
<# LWin Left Windows
+> RShift Right Shift
<^>! AltGr  
  AppsKey Menu key
  CapsLock  

Others:

  • F[1-24], Tab, Space, Enter/Return, Backspace/BS
  • Left, Up, Down, Right
  • Esc, Ins, Delete/Del, Home, End, PgUp, PgDn
  • PrintScreen, ScrollLock, CtrlBreak
  • Sleep, Pause

Numpad:

  • Numlock ON: Numpad[0-9],
  • Numlock OFF: NumpadIns, NumpadEnd, NumpadMult, NumpadEnter, …

Multimedia:

  • Browser_Stop, Media_Next, Volume_Up, Launch_App2, …

Mouse:

  • LButton, RButton, MButton
  • XButton1 (Browser_Back), XButton2 (Browser_Forward)
  • WheelUp, WheelDown, WheelLeft, WheelRight

Joystick:

  • JoyX, JoyPOV, JoyInfo, …

JoystickTest: A simple script for determining the exact mapping of your joystick.


Find the full KeyList here. If your keyboard has keys that are not in the full keylist, it might still be possible to map them to a script.

You can also let Autohotkey itself do the figuring out for you. Its builtin command KeyHistory opens a window where you can figure out which is which.

Native function

Prefix a hotkey with ~ to not block the native function.

#IfWinActive, ahk_class CabinetWClass
; Control + Shift + 6: Details View in Windows Explorer
; Resize columns so that filenames are completely visible
~^+6::Send, {Control Down}{NumpadAdd}{Control Up}
#IfWinActive

Custom combinations

To combine keys that do not have a shorthand use &. Keys on the left side of such custom combinations lose their native function. They are called prefix keys.

Example: Search google for text on the clipboard by pressing Capslock and X.

Capslock & X::Run, http://www.google.com/search?q=%clipboard%

Other

Key Down and Up
Add UP to a hotkey combination to run the script on key release rather than on keypress.

AppsKey::ToolTip Press < or > to cycle through tabs.
AppsKey Up::ToolTip
~AppsKey & <::Send ^+{tab}
~AppsKey & >::Send ^{tab}

Wildcard
* acts as a key modifier wildcard.

*#c::Msgbox Triggered by Win+C, Shift+Win+C, Ctrl+Win+C, etc

Resending
$ is necessary when you need to send the same hotkey and not execute your script again.

$#e::
; Send Control + C => Copy text
Send, ^c
ClipWait, 1
fileExists := FileExist(clipboard)
if (fileExists = "D") {
    ; Open explorer in path on clipboard
    Run % "explorer.exe /root," clipboard

} else if (fileExists) {
    ; Open explorer with file selected
    Run % "explorer.exe /select," clipboard

} else {
    ; No path on clipboard, just open explorer
    Send #e
}
Return

Advanced Hotkeys

Creating more advanced hotkey combinations.

Context sensitive hotkeys

Control in which applications a hotkey is (not) active with the keywords IfWinActive, IfWinExist, IfWinNotActive and IfWinNotExist.

#IfWinActive, ahk_class Notepad
^a::MsgBox You pressed Ctrl-A while Notepad is active. Pressing Ctrl-A in any other window will pass the Ctrl-A keystroke to that window.
#c::MsgBox You pressed Win-C while Notepad is active.
#IfWinActive

#c::MsgBox You pressed Win-C while any window except Notepad is active.


#If MouseIsOver("ahk_class Shell_TrayWnd") and true
WheelUp::Send {Volume_Up}     ; Wheel over taskbar: increase/decrease volume.
WheelDown::Send {Volume_Down} ;

MouseIsOver(WinTitle) {
    MouseGetPos,,, Win
    return WinExist(WinTitle . " ahk_id " . Win)
}
#If


$^p::
IfWinActive ahk_class Notepad
    return  ; i.e. do nothing, which causes Control-P to do nothing in Notepad.

Send ^p
return

Find out the ahk_class of a program with Window Spy (AU3_Spy.exe) which comes bundled with Autohotkey itself.

Combining 2 hotkeys

Check if a hotkey combination is pressed twice

~Esc::
; Esc twice to close an application
If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < 500)
    WinClose
Return

Gotcha: the A_PriorHotkey will only hold values of combinations that are also defined as a hotkey. The value of A_PriorHotkey will be exactly as the hotkey is defined.


Follow a hotkey up with an additional keypress

; AltGr + C: Change the case of the selected text
; Follow up with (U)PPER, l(ower) or T(itle)
<^>!c::
clipboard =
Send, ^c
ClipWait, 1
Input keyPressed, I L1
if (keyPressed = "u") {
    StringUpper toUpperCase, clipboard
    Send %toUpperCase%
} else if (keyPressed = "l") {
    StringLower toLowerCase, clipboard
    Send %toLowerCase%
} else if (keyPressed = "p" or keyPressed = "t") {
    StringUpper toTitleCase, clipboard, T
    Send %toTitleCase%
}
return

Input option L1 is the maximum allowed length. (L1 -> L5)

Double, triple and long key presses

Simple double keypress

Map a double µ keypress to a smiley.

; File needs to be encoded in UTF8 BOM
; for a binding of "µ" to work.
$µ::
    KeyWait, µ
    KeyWait, µ, D T0.2
    if ErrorLevel
        ; No second µ keypress
        SendInput µ
    Else
        ; Replace double keypress
        ; with something else
        SendInput 😀
Return

The whole shebang

#c::
DoubleClickTime := DllCall("GetDoubleClickTime") ; in milliseconds

; Wait for 'c' to be released
KeyWait, c
if (A_TimeSinceThisHotkey > DoubleClickTime) {
    Msgbox Longpress
    return
}

; Wait for 'c' to be pressed down again (option "d")
; But timeout after T0.5 seconds (If DoubleClickTime is 500)
KeyWait, c, % "d T"DoubleClickTime/1000
If ! Errorlevel
    Msgbox Doublepress
else
    Msgbox Singlepress
Return

KeyWait docs or more info on the forum.


Long middle mouse click with GetKeyState

~MButton::
HowLong = 0
Loop
{
    HowLong++
    Sleep, 10
    GetKeyState, MButton, MButton, P
    IfEqual, MButton, U, Break
}
IfLess, HowLong, 20, Return

; Do stuff when middle mouse button was pressed longer than 20ms

Triple, quadruple etc keypresses

; Example #3: Detection of single, double, and triple-presses of a hotkey. This
; allows a hotkey to perform a different operation depending on how many times
; you press it:
#j::
if winc_presses > 0 ; SetTimer already started, so we log the keypress instead.
{
    winc_presses += 1
    return
}
; Otherwise, this is the first press of a new series. Set count to 1 and start
; the timer:
winc_presses = 1
SetTimer, KeyWinC, -400 ; Wait for more presses within a 400 millisecond window.
return

KeyWinC:
if winc_presses = 1 ; The key was pressed once.
{
    Run, c:\  ; Open a folder.
}
else if winc_presses = 2 ; The key was pressed twice.
{
    Run, c:\windows  ; Open a different folder.
}
else if winc_presses > 2
{
    MsgBox, Three or more clicks detected.
}
; Regardless of which action above was triggered, reset the count to
; prepare for the next series of presses:
winc_presses = 0
return

Morse hotkeys

The forum thread on hold patterns.

Morse(timeout = 400) {
   tout := timeout/1000
   key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]")
   Loop {
      t := A_TickCount
      KeyWait %key%
      Pattern .= A_TickCount-t > timeout
      KeyWait %key%,DT%tout%
      If (ErrorLevel)
         Return Pattern
   }
}

; Use Backspace
BS::MsgBox % "Morse press pattern " Morse()

; Alt + Z
!z::
p := Morse()
If (p = "0")
  MsgBox Short press
Else If (p = "00")
  MsgBox Two short presses
Else If (p = "01")
  MsgBox Short+Long press
Else
  MsgBox Press pattern %p%
Return

Other

Waiting for something

Wait for something to happen with SetTimer

; Example #2: Wait for a certain window to appear and then alert the user:
#Persistent
SetTimer, Alert1, 500
return

Alert1:
IfWinNotExist, Video Conversion, Process Complete
    return

; Otherwise:
SetTimer, Alert1, Off  ; i.e. the timer turns itself off here.
SplashTextOn, , , The video conversion is finished.
Sleep, 3000
SplashTextOff
return

Suspension

; Toggle script suspension
^#s:: ; Control + Win + S
Suspend
Msgbox % "Script is now " (A_IsSuspended ? "suspended" : "running")
Return

The Pause keyword would halt the current thread while Suspend stops all hotkeys from triggering.

Start a script with Suspend, Permit to have that hotkey still trigger even while the script is suspended.


Stuff that came into being during the making of this post
Other interesting reads
Updates
  • 28 March 2023 : Added double keypress hotkey example
  • 25 August 2018
Tags: autohotkey