Hey Everyone!
Sharing a polished AutoHotkey script I’ve been working on. Some input and fixes by @Leaske It’s designed to auto-repeat specific keys (R
and F
by default) with customizable intervals, transparency, and additional key support. I chose R and F because I didnt have much keybound to them and I try to use macro’s with ST/MT on different keys. This lets me still have some of my own keybinds too.
Includes:
- Persistent GUI settings (saved between sessions in a .ini file)
- Transparent, draggable always-on-top window
- Minimize & restore functionality
- Custom key support (add/remove easily)
- Dynamic key repeat with modifier support (Ctrl/Alt/Shift)
- In-Game only activation (works only when WoW window is active)
Here’s the full script:
#Persistent
#SingleInstance Force
#NoEnv
SetWorkingDir %A_ScriptDir%
SetTimer, CheckWoW, 1000
global iniFile := "macro_settings.ini"
global sleepTime, transparency, macroPaused, winX, winY
global isDragging := false
global settingsVisible := false
global wowIsOpen := false
global keyList := "r,f" ; Comma-separated
global customKey := ""
global isMinimized := false
; Load saved settings
IniRead, sleepTime, %iniFile%, Settings, SleepTime, 150
IniRead, transparency, %iniFile%, Settings, Transparency, 200
IniRead, macroPaused, %iniFile%, Settings, MacroPaused, 0
IniRead, winX, %iniFile%, Settings, WinX, 100
IniRead, winY, %iniFile%, Settings, WinY, 100
IniRead, keyList, %iniFile%, Settings, KeyList, r,f
; GUI Setup
Gui, +AlwaysOnTop +ToolWindow -Caption +E0x80000
Gui, Margin, 10, 10
Gui, Color, 101010
Gui, Font, s10, Segoe UI
Gui, Add, Text, cLime w180 h20 gStartDrag, WoW Key Spammer [Drag me]
Gui, Add, Text, x+5 w20 h20 cYellow gMinimizeGui Center, _
Gui, Add, Text, x+5 w20 h20 cRed gCloseGui Center, X
Gui, Add, Text, xm y+10 cWhite, Repeat interval:
Gui, Add, Text, vSpeedDisplay x+5 w60 h20 Right cYellow, %sleepTime%ms
Gui, Add, Button, xm y+10 w95 h30 gToggleSettings, Settings
Gui, Add, Button, x+10 w95 h30 gTogglePause, % (macroPaused ? "Resume" : "Pause")
Gui, Font, s9
Gui, Add, GroupBox, vSettingsGroup w200 h150 Hidden, Settings
Gui, Add, Text, vSpeedLabel xp+10 yp+25 cWhite Hidden, Speed: %sleepTime%ms
Gui, Add, Slider, vSpeedSlider w180 Range50-300 AltSubmit gAdjustSpeed Hidden, %sleepTime%
Gui, Add, Text, vSpeedMin cGray x+0 Hidden, 50ms
Gui, Add, Text, vSpeedMax cGray xp-180 yp+15 Hidden, 300ms
Gui, Add, Text, vTransparencyLabel xp yp+25 cWhite Hidden, Transparency: %transparency%
Gui, Add, Slider, vTransparencySlider w180 Range25-255 AltSubmit gAdjustTransparency Hidden, %transparency%
Gui, Add, Text, vCustomKeyLabel xp yp+25 cWhite Hidden, Add custom key:
Gui, Add, Edit, vCustomKeyEdit w40 h20 Limit1 gSetCustomKey Hidden
Gui, Add, Button, vAddKeyButton x+5 w60 h20 gAddCustomKey Hidden, Add Key
Gui, Add, Button, vResetKeysButton x+5 w80 h20 gResetKeys Hidden, Reset to R/F
Gui, Add, Text, vMinViewLabel xm ym w200 h30 cLime Center Hidden, WoW Key Spammer (Click to restore)
Gui, Show, x%winX% y%winY% NoActivate, WoW Key Spammer
Gui, +LastFound
WinSet, Transparent, %transparency%
; Load hotkeys
Loop, Parse, keyList, `,
{
key := A_LoopField
AssignKeyHotkeys(key)
}
return
CheckWoW:
Process, Exist, Wow.exe
if (ErrorLevel != 0) {
if (!wowIsOpen) {
wowIsOpen := true
if (!isMinimized)
Gui, Show, NoActivate
}
} else {
if (wowIsOpen) {
wowIsOpen := false
Gui, Hide
}
}
return
MinimizeGui:
if (!isMinimized) {
isMinimized := true
GuiControl, Hide, SpeedDisplay
GuiControl, Hide, ToggleSettings
GuiControl, Hide, TogglePause
if (settingsVisible) {
settingsVisible := false
GuiControl, Hide, SettingsGroup
GuiControl, Hide, SpeedLabel
GuiControl, Hide, SpeedSlider
GuiControl, Hide, SpeedMin
GuiControl, Hide, SpeedMax
GuiControl, Hide, TransparencyLabel
GuiControl, Hide, TransparencySlider
GuiControl, Hide, CustomKeyLabel
GuiControl, Hide, CustomKeyEdit
GuiControl, Hide, AddKeyButton
GuiControl, Hide, ResetKeysButton
}
GuiControl, Show, MinViewLabel
Gui, Show, w150 h30 NoActivate
}
else {
Gosub, RestoreGui
}
return
RestoreGui:
isMinimized := false
GuiControl, Hide, MinViewLabel
GuiControl, Show, SpeedDisplay
GuiControl, Show, ToggleSettings
GuiControl, Show, TogglePause
Gui, Show, AutoSize NoActivate
return
CloseGui:
ExitApp
return
StartDrag:
if (isMinimized) {
Gosub, RestoreGui
return
}
PostMessage, 0xA1, 2
return
GuiSize:
WinGetPos, winX, winY
IniWrite, %winX%, %iniFile%, Settings, WinX
IniWrite, %winY%, %iniFile%, Settings, WinY
return
AdjustSpeed:
GuiControlGet, sleepTime,, SpeedSlider
GuiControl,, SpeedLabel, Speed: %sleepTime%ms
GuiControl,, SpeedDisplay, %sleepTime%ms
IniWrite, %sleepTime%, %iniFile%, Settings, SleepTime
return
AdjustTransparency:
GuiControlGet, transparency,, TransparencySlider
GuiControl,, TransparencyLabel, Transparency: %transparency%
WinSet, Transparent, %transparency%
IniWrite, %transparency%, %iniFile%, Settings, Transparency
return
ToggleSettings:
settingsVisible := !settingsVisible
GuiControl, % (settingsVisible ? "Show" : "Hide"), SettingsGroup
GuiControl, % (settingsVisible ? "Show" : "Hide"), SpeedLabel
GuiControl, % (settingsVisible ? "Show" : "Hide"), SpeedSlider
GuiControl, % (settingsVisible ? "Show" : "Hide"), SpeedMin
GuiControl, % (settingsVisible ? "Show" : "Hide"), SpeedMax
GuiControl, % (settingsVisible ? "Show" : "Hide"), TransparencyLabel
GuiControl, % (settingsVisible ? "Show" : "Hide"), TransparencySlider
GuiControl, % (settingsVisible ? "Show" : "Hide"), CustomKeyLabel
GuiControl, % (settingsVisible ? "Show" : "Hide"), CustomKeyEdit
GuiControl, % (settingsVisible ? "Show" : "Hide"), AddKeyButton
GuiControl, % (settingsVisible ? "Show" : "Hide"), ResetKeysButton
GuiControl,, ToggleSettings, % (settingsVisible ? "Close" : "Settings")
Gui, Show, AutoSize NoActivate
return
SetCustomKey:
GuiControlGet, customKey,, CustomKeyEdit
return
AddCustomKey:
if (RegExMatch(customKey, "^[a-zA-Z0-9]$") && !InStr(keyList, customKey)) {
keyList .= "," customKey
IniWrite, %keyList%, %iniFile%, Settings, KeyList
AssignKeyHotkeys(customKey)
}
return
ResetKeys:
keyList := "r,f"
IniWrite, %keyList%, %iniFile%, Settings, KeyList
Reload
return
TogglePause:
macroPaused := !macroPaused
GuiControl,, TogglePause, % (macroPaused ? "Resume" : "Pause")
IniWrite, %macroPaused%, %iniFile%, Settings, MacroPaused
return
AssignKeyHotkeys(key) {
Hotkey, IfWinActive, World of Warcraft
Hotkey, $%key%, CustomKeyPressed
Hotkey, $^%key%, CustomKeyPressed
Hotkey, $+%key%, CustomKeyPressed
Hotkey, $!%key%, CustomKeyPressed
Hotkey, IfWinActive
}
CustomKeyPressed:
HandleKey(SubStr(A_ThisHotkey, InStr(A_ThisHotkey, "$") + 1))
return
#IfWinActive World of Warcraft
HandleKey(key) {
if (macroPaused) {
SendInput % key
return
}
Loop {
if !GetKeyState(key, "P")
break
modifiers := ""
modifiers .= GetKeyState("Ctrl", "P") ? "^" : ""
modifiers .= GetKeyState("Shift", "P") ? "+" : ""
modifiers .= GetKeyState("Alt", "P") ? "!" : ""
SendInput {Blind}%modifiers%%key%
Sleep %sleepTime%
}
}
; Default key handlers
$r::
$^r::
$+r::
$!r::
HandleKey("r")
return
$f::
$^f::
$+f::
$!f::
HandleKey("f")
return