Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Macro recorder

  • This topic is locked This topic is locked
56 replies to this topic
  • Members
  • 280 posts
  • Last active: May 29 2009 06:39 PM
  • Joined: 16 Jun 2007
won't stop create a stop boutton please.

Also Option to use

coordmode, mouse, screen
coordmode, pixel, screen

Instead of regular coord.

Also a help file, or a tooltip that appear to explain what is
Timeintervals, rel all that.

And a option to record like that (like the autoscript write)
WinWait, Recorder by Titan (v0.11a),
IfWinNotActive, Recorder by Titan (v0.11a), , WinActivate, Recorder by Titan (v0.11a),
WinWaitActive, Recorder by Titan (v0.11a),

Timeinterval is so great, that will change my whole way to see AHK.

Thanks Santa that is what I asked for Xmas. :lol:

  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
Thanks for the suggestions, I've added them to my list:
[*:5x8apewx]Add stop button (similar to ASW)
[*:5x8apewx]Make options for CoordMode
[*:5x8apewx]Use tooltip messages to briefly explain each option (and get German translations)
[*:5x8apewx]Use WinWait and WinActivate prior to WinWaitActive.With all my school work I find very little free time so I can't say when this will be done - plus I'd hate to disappoint you by giving a time scale and not meeting the deadline. What I can promise is that v0.13a will include a lot of cool features.

  • Members
  • 7 posts
  • Last active: Apr 04 2010 09:34 AM
  • Joined: 21 May 2008
I'm wanting to automate some Flash games, and this looks great! I've looked to see if there are any more recent updates in other threads, but couldn't find anything. Here are a couple of comments on this version.

First, looking at the logkey() function, it appears that if the gui_sleep checkbox is true, then the "Sleep" statement gets inserted after the "Click" statement. I'd think you'd want it before.

Second, I'm going to add a gui_pixel checkbox that will cause the generated script to loop until the pixel at the mouse location becomes a particular color. Especially in the game I'm working on, content is downloaded frequently, and a fixed sleep isn't appropriate. Instead, I want to wait for a GUI element to be drawn, however long or short it takes.

  • Members
  • 13 posts
  • Last active: Aug 31 2008 03:16 AM
  • Joined: 06 Aug 2008
MAN ITS SCREWING UP i record the macros and than when i play it back the mouse movements arnt what i recorded they start going crazy

  • Members
  • 129 posts
  • Last active: Dec 28 2013 04:31 PM
  • Joined: 26 Sep 2008
I assume that the link in the first post of this thread point always to the current version.
I have found 2 errors that prevent my first script to work :
Sl{e 2}p, 32579
Error : this ligne does not contain a recognized action.
So I have changed all occurences of "Sl{e 2}p," to "Sleep,"
2) and it goes farther but the tittle of a screen of the recorded application includes "100%" and my script complains that their is a % missing around a variable name. You should probably include an escape character before each % character...

BTW : I don't like the fact that you replace multiple occurrences of a character because the script become difficult to read (in particular cla{s 2} instead of class)

  • Members
  • 129 posts
  • Last active: Dec 28 2013 04:31 PM
  • Joined: 26 Sep 2008
The 2) problem is more general see #EscapeChar (and explanation of escape sequences) in the help.
Characters to be escaped by AHK may be perfectly legitimate for the recorded application either in the data sent and that AHK process e.g. the tittle of the screen (are there others ?) or in the data typed by the user in an input field that AHK sends to the application.

  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012


I have found 2 errors that prevent my first script to work

I have discontinued this script although I made a note to revisit some day. In the mean time feel free to start a fork if you know how to fix said bugs.

  • Members
  • 63 posts
  • Last active: Apr 30 2014 06:35 PM
  • Joined: 11 Nov 2008
I know you guys mean well and everything, and the tool is amazing, I use it mainly as a universal auto correct, but I really wish the OS community would grasp the concept of ignorance.

Some people are not born with this stuff built in. A readme with install and use instructions would rock.

On behalf of newbs everywhere, Thanks in advance.


  • Members
  • 61 posts
  • Last active: Sep 15 2015 05:12 PM
  • Joined: 25 Aug 2007
OMG this is the answer to all of my prayers if it worked 100%

i script recorder that actually records everything would make 1/2 the new people not become discouraged.

TITAN i pray one day you come back to this. And when you do think of us the lil guy. :)

  • Members
  • 6 posts
  • Last active: Feb 02 2009 11:24 PM
  • Joined: 17 Jan 2009
Looks... interesting. Thanks for it.

  • Members
  • 25 posts
  • Last active: Jul 05 2010 05:29 PM
  • Joined: 04 Mar 2009
It seems that sometimes wParam=4 isn't enough to detect WinActivate.
Google answered me that HSHELL_RUDEAPPACTIVATED = 32772

So probably the line:
should be changed to:

With this, it seems to work fine.

  • Members
  • 25 posts
  • Last active: Jul 05 2010 05:29 PM
  • Joined: 04 Mar 2009
Good news everyone!

Titan's recorder is so good an idea (100% AHK!), that I wanted to contribute on what I could.

So here is a new version with some bug fixes, although I did not take all the remarks into account...

Major changes : french translation, relative/absolute coords bug fixed, WinWait etc. before WinActivate, sleep times more accurate (grep.ahk not used anymore), ...
See the head of the code for more info.

Download Titan's recorder on first page and then replace the contents of Recorder.ahk by the following code.
Then launch Recorder.ahk

; Authors: Titan, BoBo¨, Metaxal
; GNU General Public License 3.0 or higher <http://www.gnu.org/licenses/gpl-3.0.txt>

   original topic:

   Version history:
    - 0.17m (Metaxal)
        - bugfix: moverel now moves the mouse relatively to the initial mouse coordinates
        - added "WAIT!" message 
        - (bug) added var gui_windowrel, to move in Coordmode Relative, NOT YET FUNCTIONAL!
            added gui control
            (Russian and German traductions for this are approximate)
    - 0.16m (Metaxal)
        - added: Russian text by Anton Bukov
   - 0.15m (Metaxal)
      - added: ExitApp key in generated scripts (the same key as the one used to stop recording, which makes sense!)
      - added NumpadEnter as bug key
      - added Replay button, script saved by default in temp.ahk
   - 0.14m (Metaxal)
      - fixed: buggy keys (Delete, Home, PgUp, ...) not logged
      - fixed: recording mouse moves was not functional?
      - not tested: relative mouse moves
   - 0.13m (Metaxal)
      - fixed: mouse clicks not recorded relative to screen...
      - Using VK codes instead of explicit symbols
         -> no problem whatever the foreign keyboard?
         -> can handle mysterious keys !
         -> handles mouse up and down + joysticks (?)
   - 0.12m (Metaxal)
      - french translation
      - removed consolidate, added add_log
      -> no need for #Include grep.ahk anymore. Multiple "Sends" are still merged, but "aaaa" is no more compressed
      -> also corrects the "Sl{e 2}p" error
      - added WinWait, IfWinActive and WinWaitActive
      - F11 and F12 for start/stop prefered to avoid some bugs with combined hotkeys
      - fixed: WinActivate not detected (wParam=32772)
      - fixed: "Send, " without parameter was added at end of script
      - fixed: mouse cordinates not relative or absolute
      - fixed(?): pressing Shift or Control at beginning of script would go to some other hotkey label
      (sometimes stop, sometimes start, or even exit when *~Esc is active)
      resolved by placing the call to hotkeys() before initializing the start and stop hotkeys
      Not sure this is completely fixed
      - fixed: wrong Sleep times
      - fixed: Sleep not initialized at each new recording
      - NOT fixed: keys are sometimes missed, and sometimes added??
   - 0.11a
      Original version by Titan, german translations by BoBo¨

   - Add a tooltip in the generated script to show when the script is playng or is ended.

#SingleInstance ignore

#Include %A_ScriptDir% ; Metaxal: Ensures a consistent #Include directory
#Include Anchor.ahk
; #Include grep.ahk ; Metaxal: not needed anymore

SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

SetBatchLines, -1
CoordMode, ToolTip, Screen
CoordMode, Mouse, Screen

lang_table =
( Join`n `
Recorder by Titan,Titans Makro Recorder, Enregistreur de macro par Titan,Генератор макросов Titan-а
Recording options,Aufnahmeoptionen,Options d'enregistrement,Опции записи
&Time intervals,&Zeitintervalle,&Intervalles de temps,Временные интервалы
&Window actions,&Fensteraktionen,&Gestion des fenetres,Действия над окнами
&Use control commands,&Control-Befehle,&Commandes de controle,Действия над элементами управления
&Keyboard actions,&Tastaturaktionen,C&lavier,Нажатия клавиш
Mouse c&licks,&Mausklicks,Clics &souris,Клики мышкой
Hotkeys,Hotkeys,Hotkeys,Горячие клавиши
&Save As...,&Speichern unter...,&Enregistrer sous...,Сохранить как...
Save As...,Speichern unter...,Enregistrer sous...,Сохранить как...
AutoHotkey Scripts,AutoHotkey Scripts,AutoHotkey ScriptsбAutoHotkey скрипты
Recording macro...`nPress $1 to stop.,Makroaufzeichnung...`nBeenden mit $1,Enregistrement en cours...`nAppuyez sur $1 pour arreter,Запись макроса... `nДля остановки нажмите $1
"Loading script, please wait...","Lade Skript, bitte warten...","Chargement du script, veuillez patienter..."б"Скрипт загружается..."
Save script,Skript speichern,Enregistrer le script,Сохранить скрипт
Would you like to save the current script before closing?,Vor Beenden speichern?,Enregistrer avant de quitter ?,Сохранить изменения?
Window Rel, Fenster Rel, Rel Fenetre, по отношению к окну

If A_Language in 0407,0807,0c07,1007,1407
   lang = de
Else If A_Language in 040c,080c,0c0c,100c,140c,180c
   lang = fr
Else If A_Language in 0409
   lang = ru
Else lang = en ; default

i = -1
Loop, Parse, lang_table, `n
   Loop, Parse, A_LoopField, CSV
      If i = 0
         If lang = %A_LoopField%
            j = %A_Index%
      Else If A_Index = %j%
         lang%i% = %A_LoopField%

title = Recorder
vers = 0.14m
config = %A_AppData%\%title%.ini
config_list = clicks,keyboard,window,ctrl,sleep,movements=0,movint=10,moveinte=10,moverel=0,start=F11,stop=F12,play=F9,windowrel=0
Loop, Parse, config_list, `,
   StringSplit, v, A_LoopField, =
   IniRead, gui_%v1%, %config%, Options, %v1%, % InStr(A_LoopField, "=") ? v2 : 1

Gui, +Resize +MinSize +LastFound
; fixed width font is too big
Gui, Add, Edit, vscr Hwndhscr w350 h200 gType
Gui, Font
Gui, Add, GroupBox, vsec1 Section ym w200 r7.5, %lang2%
Gui, Add, CheckBox, vgui_sleep xp+15 yp+25 Checked%gui_sleep%, %lang3%
Gui, Add, CheckBox, vgui_window Checked%gui_window%, %lang4%
Gui, Add, CheckBox, vgui_ctrl Checked%gui_ctrl% Disabled, %lang5%
Gui, Add, CheckBox, vgui_keyboard Checked%gui_keyboard%, %lang6%
Gui, Add, CheckBox, vgui_clicks Checked%gui_clicks%, %lang7%
Gui, Add, CheckBox, vgui_movements Checked%gui_movements% gMov, %lang8%
Gui, Add, Edit, vgui_moveinte xp+85 yp-2 w50 Limit4
Gui, Add, UpDown, vgui_movint Range1-5000, %gui_movint%
Gui, Add, CheckBox, vgui_moverel xp-60 yp+25 Checked%gui_moverel%, %lang9% ;xp+60 yp+2 
Gui, Add, CheckBox, vgui_windowrel xp+40 yp Checked%gui_windowrel%, %lang24% ;xp-60 yp+20 
Gui, Add, GroupBox, vsec2 xs w200 r5, %lang10%
Gui, Add, Text, vlbl1 xp+15 yp+25, %lang11%:
Gui, Add, Hotkey, vgui_start xp+40 yp-2 Limit1 gHotkey, %gui_start%
Gui, Add, Text, vlbl2 xp-40 yp+27, %lang12%:
Gui, Add, Hotkey, vgui_stop xp+40 yp-2 Limit1 gHotkey, %gui_stop%
Gui, Add, Text, vlbl4 xp-40 yp+29, %lang22%:
Gui, Add, Hotkey, vgui_play xp+40 yp-2 Limit1 gHotkey, %gui_play%
Gui, Add, Button, vsave Section xm yp+10 Disabled gSave, %lang13%
Gui, Add, Button, vclear ys w55 Disabled gClear, %lang14%
Gui, Add, Button, vlbl3 xm+295 ys w55 Default gStart, %lang11%
Gui, Show, , %lang1% (v%vers%)

SendMessage, 208, 0, RegisterCallback("EditWordBreakProc"), , ahk_id %hscr%

GoSub, Mov

; adapted from Skan's script at http://www.autohotkey.com/forum/viewtopic.php?p=123323#123323:
DllCall("RegisterShellHookWindow", "UInt", WinExist())
OnMessage(DllCall("RegisterWindowMessage", "Str", "SHELLHOOK"), "ShellMessage")

GuiControlGet, v, , gui_start
If v !=
   Hotkey, %v%, Start
GuiControlGet, v, , gui_stop
If v !=
   Hotkey, %v%, Stop
GuiControlGet, v, , gui_play
If v !=
   Hotkey, %v%, PlayTemp


Anchor("scr", "wh")
v = sec1,gui_movint,gui_clicks,gui_keyboard,gui_window,gui_ctrl,gui_sleep,gui_movements,gui_movint,gui_moverel,sec2,lbl1,gui_start,lbl2,gui_stop,gui_play,lbl4,gui_moveinte,gui_windowrel
Loop, Parse, v, `,
   Anchor(A_LoopField, "x", true)
Anchor("save", "y")
Anchor("clear", "xy")
Anchor("lbl3", "xy")

GuiControlGet, v, , gui_movements
GuiControl, Enable%v%, gui_moveinte
GuiControl, Enable%v%, gui_moverel

;GuiControl, , scr
ControlSend, , ^{Home}^+{End}{Del}, ahk_id %hscr% ; this allows undo
GuiControlGet, scr, , scr
v := StrLen(scr) > 0
GuiControl, Enable%v%, save
GuiControl, Enable%v%, clear
unsaved := true

GuiControlGet, scr, , scr
Gui, +OwnDialogs
FormatTime, d, , ShortDate
FormatTime, t, , Time
StringReplace, t, t, :, .
StringReplace, d, d, /, -, All
FileSelectFile, file, S19, %A_MyDocuments%\%lang15% %d% %t%.ahk, %lang13%, %lang17% (*.ahk; *.txt)
If file =
FileDelete, %file%
FileAppend, %scr%, %file%
unsaved := false
VarSetCapacity(scr, 0)

ToolTip, %lang23%, 5, 5
hotkeys(true) ; Metaxal: needs to be BEFORE setting gui_start and gui_stop??
Gosub, Hotkey
GuiControlGet, v, FocusV
If v in gui_start,gui_stop
GuiControlGet, v, , gui_stop
StringReplace, s, lang18, $1, %v%
StringReplace, s, s, ``n, `n
Gui, Submit
GuiControlGet, gui_movint, , gui_moveinte
log_mpx := 0
log_mpy := 0
log_s = 1
log_xt := A_TickCount ; Initialize sleep counter
log_text .= "#NoEnv`n" ; SendMode Input`n" ; buggy with mousemove! (not synchronous)
add_log("CoordMode", "Mouse, " . (gui_windowrel ? "Relative" : "Screen"))
if gui_windowrel ; Not yet functional!
   CoordMode, Mouse, Relative
   CoordMode, Mouse, Screen
add_log("SetMouseDelay",  "2")   

If (gui_movements and gui_movint > 0 and gui_movint <= 5000) {
   ;MsgBox timer=%gui_movint%
   SetTimer, MouseMov, %gui_movint%

ToolTip, %s%, 5, 5

;Loop {
;   Input, v, L1 V ; now useless
;   logkey(v)
;   If !log_s
;      Break


log_s = 0
ToolTip, %lang19%, 5, 5
SetTimer, MouseMov, Off
Gui, Show
GuiControlGet, v, , log_text
If v
   v .= "`n"
log_text .= "`nExitApp`n" . gui_stop . "::ExitApp`n" ; the exit key is the one used to stop the script!
FileDelete temp.ahk
FileAppend %log_text%, temp.ahk
GuiControl, , scr, %v%%log_text%
VarSetCapacity(log_text, 0)
ControlSend, , ^{End}, ahk_id %hscr%
Goto, Type

If log_s {
   StringTrimLeft, v, A_ThisHotkey, 2 ; -2 to remove "~*"

   MouseGetPos, x, y
   If (x != log_mpx or y != log_mpy) {
      If gui_moverel
         add_log("MouseMove ", (log_mpx ? x - log_mpx : 0) . ", " . (log_mpy ? y - log_mpy : 0) . ",, R")
         add_log("MouseMove", x . ", " . y)
   log_mpx := x
   log_mpy := y


   Run %A_AhkPath% temp.ahk

;~*Esc:: ; for debugging
GuiControlGet, scr, , scr
If (scr != "" and unsaved)
   Gui, +OwnDialogs
   MsgBox, 20, %lang20%, %lang21%
   IfMsgBox, Yes
      Gosub, Save
Gui, Submit
Loop, Parse, config_list, `,
   StringSplit, v, A_LoopField, =
   IniWrite, % gui_%v1%, %config%, Options, %v1%

; Metaxal
add_log(cmd, params) {
   global last_cmd, log_text, log_xt, gui_sleep, log_xt

   If gui_sleep and (cmd != "Sleep") {
      v := Round((A_TickCount - log_xt) / 1)
      If (log_text and v > 700)
         add_log("Sleep", v) ; 
      log_xt := A_TickCount

   If (SubStr(cmd, 1, 4) = "Send") and (cmd = last_cmd)
      log_text .= params
      log_text .= "`n" . cmd . ", " . params
   last_cmd = %cmd%

logkey(v) {
   local _w, _ct
   k := SubStr(v, 1, 4)
   if v not contains up
      v = %v% down
   v = {%v%}
   ; VK codes can also detect mouse down and up !!
   if k in VK01,VK02,VK04 ; mouse clicks
      If gui_clicks {
         GoSub MouseMov
         add_log("Send", v) ; Synchronous click
   Else If gui_keyboard {
      add_log("SendInput", v)

ShellMessage(wParam, lParam) {
   local t, c
      WinGetTitle, t, ahk_id %lParam%
      WinGetClass, c, ahk_id %lParam%
      If (log_s and gui_window and t and c) {
         d := t . " ahk_class " . c
         ;add_log("WinWait", d)
         add_log("IfWinNotActive", d . ", , WinActivate, " . d)
         add_log("WinWaitActive", d)

hotkeys(on = true) {

   ; VK codes seem to be much more reliable concerning different keyboard configurations.
   ; also handles properly the down and up of several keys, even mouse ones.
   ; also handles joysticks ?!
   ; This should allow for *any* foreign keyboard (?)
   ; although it is not very readable, so the script cannot really be modified manually
   StringSplit numarray, nums

   Loop %numarray0%
      n1 := numarray%A_Index%
      Loop %numarray0%
         n2 := numarray%A_Index%
         n := n1 . n2
         if n=00
         k := "*~VK" . n
         Hotkey, %k%, LogKey, % "B" . (on ? "On" : "Off") ;%
         Hotkey, %k% up, LogKey, % "B" . (on ? "On" : "Off") ;%
   Loop, Parse, bugkeys, `,
      k =  ~*%A_LoopField%
      Hotkey, %k%, LogKey, % "B" . (on ? "On" : "Off") ;%
      Hotkey, %k% up, LogKey, % "B" . (on ? "On" : "Off") ;%

; taken from http://www.autohotkey.com/forum/topic20337.html
EditWordBreakProc(lpch, ichCurrent, cch, code) {
   static exp = "\W" ; treat any non alphanumeric character as a delimiter with this regex
   Loop, % cch * 2 ; build the string: ;%
      str .= Chr(*(lpch - 1 + A_Index))
   If code = 0 ; WB_LEFT
      ; reverse and return last match:
      StringMid, str, str, 1, --ichCurrent
      Loop, Parse, str
         rev := A_LoopField . rev
      Return, ichCurrent - RegExMatch(rev, exp, "[^" . exp . "]+$") + 1
   Else If code = 1 ; WB_RIGHT
      Return, ichCurrent >= cch ? cch : RegExMatch(str, exp, "", ichCurrent + 1) - 1
   Else If code = 2 ; WB_ISDELIMITER
      Return, RegExMatch(SubStr(str, ichCurrent, 1), exp)

Edit 1: major changes! Now the Recorder uses VK codes, so it should be completely independent of the keyboard layout (German, French or whatever), there is no problem of missing key strokes (no using "Input" anymore), + it can handles various mouse and joysticks buttons!
Now recording keypresses should be much more reliable!
The drawback is that the generated scripts become difficult to read and modify (however I don't personaly care, generally).

Edit 2: added one line of code, recording absolute mouse clicks was not fully functional.

Edit 3: Added Russian (by Anton Bukov)

Edit 4: Added Relative to initial mouse coordinates

  • Members
  • 25 posts
  • Last active: Jul 05 2010 05:29 PM
  • Joined: 04 Mar 2009

This version should work quite well (at least it does on my machine).
You can now record while drawing in paint!
All keys should be logged, whatever the keyboard layout.

- Mouse moves should be correctly recognized.
- Fixed: some keys were not logged.
- Removed WinWait: this could hang the script in some cases (although I could use a timeout...)

Tell me what you think!
(see previous post for installation)

- Automatic save to temp file + added button to playback instantly !
- AppExit button: when the script is played back, if you press the button that was used to stop recording, this exits the generated script.

Now you can record you drawing in paint with F11 for example, stop it with F12, play it back with F9, and if you want to abruptly interrupt the playback, just press F11.

  • Members
  • 25 posts
  • Last active: Jul 05 2010 05:29 PM
  • Joined: 04 Mar 2009
I need feedback, does it work for other people too?

  • Members
  • 15 posts
  • Last active: Oct 12 2010 06:06 PM
  • Joined: 28 Mar 2009
#Include file "Anchor.ahk" cannot be found.