Skip to content

AutoHotkey

Created: 2017-07-22 17:15:51 -0700 Modified: 2020-08-27 17:50:52 -0700

  • When making a script, you’ll probably be making edits pretty frequently to it, so it’s helpful to add Reload code to it (reference). Just copy/paste all of this into a new script and remove it when you’re done writing the script:
; Win+alt+R → restart this script.
#!r::
; Show a message box briefly indicating that this is doing something...
MsgBox , , , "Reloading", 0.5
Reload
Sleep 1000 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached.
MsgBox, 4,, The script could not be reloaded. Would you like to open it for editing?
IfMsgBox, Yes, Edit
return
  • Interacting with the system tray
    • If you ever find yourself wanting to interact with the system tray, do not write your own code for this. Use FanaticGuru’s library (reference). I had tried using ImageSearch to find an icon so that I could click it, but it never actually located the icon I wanted (perhaps because it was too small? I tried a ton of things and couldn’t get it to work unless I found a larger icon on my screen).
      • To use the script, I just copy/pasted the whole thing into my file, then did this to double-click an icon: TrayIcon_Button(“lcore.exe”, “L”, True)
  • Functions
    • Definition
IsWindowWidthEnough(desiredWidth)
{
WinGetPos, , , Width, , ahk_exe LCore.exe
if Width > desiredWidth
return True
return False
}
  • Calling
isBigEnough := IsWindowWidthEnough(500)
; When running with "./script.ahk hi", this will say "hi"
firstUserArg := A_Args[1]
MsgBox %firstUserArg%
  • Something that will grab the URL from the last-activated Chrome tab and put it on the clipboard.

Esc::

BreakLoop = 1

return

F8::

Loop,

{

if (BreakLoop = 1)

break

;rest of loop code

}

return

Having a script automatically update itself and reload

Section titled Having a script automatically update itself and reload

This script does a FileAppend to itself and then called “Reload”: https://www.autohotkey.com/docs/Hotstrings.htm#Helper

(just see reference link)

Example code below to get an environment variable representing a path, add to it, then use it in a command

EnvGet, StartOfPath, BOTLAND_REPOS_ROOT
EndOfPath = botland
WorkingDir := StartOfPath . EndOfPath
Run, ConEmu64.exe -Dir %WorkingDir% -cmd -new_console jsfind %SearchString%
InputBox, SearchString, Enter arguments for jsfind, , , 640, 100
if ErrorLevel
; you pressed cancel
return
Run, ConEmu64.exe -cmd -new_console jsfind %SearchString%
return

I don’t know why this is always so hard to figure out while searching:

WinActivate, ahk_exe blender.exe

Using unicode characters like ⅚ or emojis

Section titled Using unicode characters like ⅚ or emojis

Newer versions of AHK (v1.0.90+) support sending Unicode characters with

Send {U+215A}

or

Send ⅔

Make sure to save the file with “UTF-8 with BOM” if it’s not working (in Sublime: file —> save with encoding).

List of Unicode characters

Old way (reference)

UPDATE: it’s a bad idea to use AHK to do this since your device number can change on reboot, so I ended up using this very simple Node script instead (although note that the AHK script below does work, it just required too many modifications for me to continue to use):

const microphone = require("win-audio").mic;
microphone.set(65); // set volume to 65%

What I did was run this script (after verifying it didn’t do anything malicious) to figure out which component type and device number I needed for my microphone. This was easy to spot because I’d set my microphone volume to something unique, so I found that it was MASTER:1 and device number = 10.

I ended up doing this to set the mic volume to 65:

SoundSet, 65, MASTER:1, VOLUME, 10

To just toggle the microphone’s mute, I can use this:

SoundSet, +1, MASTER:1, MUTE, 10

; This sets the speaker volume to 8%.

SoundSet, 8, MASTER:1, VOLUME, 3

Just FYI: that last number (the mixer) changed for me at one point for some reason (from 3 to 4).

Simple script to set the clipboard, paste, then reset the clipboard (reference)

Section titled Simple script to set the clipboard, paste, then reset the clipboard (reference)

pasteContent = Some text you want to send

Clipboard := pasteContent

Send,

Clipboard :=

Copy some text, mutate it, and paste it back

Section titled Copy some text, mutate it, and paste it back

; ctrl+alt+G

; Sat 07/22/2017 - 05:01 PM

; Usage: there’s an option in BTTV where double-clicking a name will write a

; message like this: “@Adam13531, ”.

;

; This converts that name into a command like “!gift Adam13531 1” for easy

; gifting of points.

^!g:: ;

OldClipboard = %clipboard%

Send {Home} ; Go to beginning of line

Send +{End} ; Highlight to end of line

clipboard = ; Reset the current clipboard so we can wait for it to be populated instead of using a timeout.

Send ^c ; Copy the current selection.

ClipWait ; Wait for Windows to populate the clipboard…

clipboard := RegExReplace(clipboard, ”@(.*?), ”, “!gift $1 1”)

Send

Sleep, 100 ; make sure we don’t send the old clipboard

clipboard = %OldClipboard%

Copy/paste user messages from Twitch

Section titled Copy/paste user messages from Twitch

; ctrl+alt+shift+C

; Sat 07/22/2017 - 05:57 PM

; Selecting text in BTTV sucks because you get a bunch of badge-related information.

; This trims that.

; Sample input (just select the text and run the shortcut):

;

; 12:50 cheer 10000 sampleperson_: HI THERE

; 12:50 6-Month Subscriber anotherperson: what’s up

; 12:50 Twitch Prime athirdperson: HeyGuys

; 12:51 pleb: lol

;

; Sample output (which will be on the clipboard):

; 12:50 sampleperson_: HI THERE

; 12:50 anotherperson: what’s up

; 12:50 athirdperson: HeyGuys

; 12:51 pleb: lol

^!+c::

clipboard = ; Reset the current clipboard so we can wait for it to be populated instead of using a timeout.

Send ^c ; Copy the current selection.

ClipWait ; Wait for Windows to populate the clipboard…

finalText =

; Loop over lines in the clipboard.

Loop, parse, clipboard, n, r

{

; Maintain the same newlines that we had originally

if (A_Index > 1) {

finalText := finalText . “`n”

}

;

replaced := RegExReplace(ALoopField, ”^(d+:d+)s+.?(w+:)(._)”, “11 2$3”)

finalText := finalText replaced

}

Clipboard := finalText

; Show a notification that won’t make sound.

SplashTextOn, 400, 50, AutoHotkey Copier, Copied text!

WinMove, AutoHotkey Copier, , 0, 0 ; Move the splash window to the top left corner.

Sleep, 1000

SplashTextOff

Return

Resizing a window taking its border into account (originally from PWS on Discord)

Section titled Resizing a window taking its border into account (originally from PWS on Discord)
; This is magic taken from https://github.com/DannyBen/Gridy/issues/1#issuecomment-220991606
GetSideBorder() {
SysGet out, 32
Return out
}
GetTopBorder() {
SysGet out, 33
Return out
}
ResizeWin( x, y, w, h ) {
; Windows 10 add an invisible border around windows which is ~6 pixels.
; Electron apps take over these borders and make the window just a little
; bigger, which is especially annoying when tiling windows.
WinGet, pname, ProcessName, A
if (pname = "Code.exe" or pname = "Discord.exe") {
w -= GetSideBorder()
h -= GetTopBorder()
}
; Some extra padding is required for some reason
if (x != 0) {
x += 2
}
if (y != 0) {
y += 2
h -= 2
}
w += GetSideBorder()
x -= GetSideBorder()
w -= 2
WinRestore, A ; Maximized windows can't be tiled, this unmaximized them
winMove, A,, x, y, w+GetSideBorder(), h+GetTopBorder()
}
; 2x1 tiling (super+numpad)
#Numpad4::
ResizeWin(0, 0, 1200, 1040)
return
#Numpad6::
ResizeWin(1200, 0, 720, 1040)
return
; 2x2 tiling (super+numpad)
#Numpad7::
ResizeWin(0, 0, 1200, 640)
return
#Numpad1::
ResizeWin(0, 640, 1200, 400)
return
#Numpad9::
ResizeWin(1200, 0, 720, 640)
return
#Numpad3::
ResizeWin(1200, 640, 720, 400)
return