Created
June 4, 2020 11:01
-
-
Save aqzlpm11/9ecd3465d7706b1b35f89719d837d1c9 to your computer and use it in GitHub Desktop.
Recording script for AHK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;----------------------------------- | |
; Macro Recorder v2.1 By FeiYue | |
; | |
; Description: This script records the mouse | |
; and keyboard actions and then plays back. | |
; | |
; F1 --> Record(Screen) (CoordMode, Mouse, Screen) | |
; F2 --> Record(Window) (CoordMode, Mouse, Window) | |
; F3 --> Stop Record/Play | |
; F4 --> Play LogFile | |
; F5 --> Edit LogFile | |
; F6 --> Pause Record/Play | |
; | |
; Note: | |
; 1. press the Ctrl button individually | |
; to record the movement of the mouse. | |
; 2. Shake the mouse on the Pause button, | |
; you can pause recording or playback. | |
;----------------------------------- | |
#NoEnv | |
SetBatchLines, -1 | |
Thread, NoTimers | |
CoordMode, ToolTip | |
SetTitleMatchMode, 2 | |
DetectHiddenWindows, On | |
;-------------------------- | |
LogFile:=A_Temp . "\~Record.txt" | |
UsedKeys:="F1,F2,F3,F4,F5,F6" | |
Play_Title:=RegExReplace(LogFile,".*\\") " ahk_class AutoHotkey" | |
;-------------------------- | |
Gui, +AlwaysOnTop -Caption +ToolWindow +E0x08000000 +Hwndgui_id | |
Gui, Margin, 0, 0 | |
Gui, Font, s12 | |
s:="[F1]Record(Screen),[F2]Record(Window)," | |
. "[F3]Stop,[F4]Play,[F5]Edit,[F6] Pause " | |
For i,v in StrSplit(s, ",") | |
{ | |
j:=i=1 ? "":"x+0", j.=InStr(v,"Pause") ? " vPause":"" | |
Gui, Add, Button, %j% gRun, %v% | |
} | |
Gui, Add, Button, x+0 w0 Hidden vMyText | |
Gui, Show, NA y0, Macro Recorder | |
OnMessage(0x200,"WM_MOUSEMOVE") | |
;-------------------------- | |
SetTimer, OnTop, 2000 | |
OnTop: | |
Gui, +AlwaysOnTop | |
return | |
Run: | |
if IsLabel(k:=RegExReplace(RegExReplace(A_GuiControl,".*]"),"\W")) | |
Goto, %k% | |
return | |
WM_MOUSEMOVE() { | |
static OK_Time | |
ListLines, Off | |
if (A_Gui=1) and (A_GuiControl="Pause") | |
and (t:=A_TickCount)>OK_Time | |
{ | |
OK_Time:=t+500 | |
Gosub, Pause | |
} | |
} | |
ShowTip(s:="", pos:="y35", color:="Red|00FFFF") { | |
static bak, idx | |
if (bak=color "," pos "," s) | |
return | |
bak:=color "," pos "," s | |
SetTimer, ShowTip_ChangeColor, Off | |
Gui, ShowTip: Destroy | |
if (s="") | |
return | |
; WS_EX_NOACTIVATE:=0x08000000, WS_EX_TRANSPARENT:=0x20 | |
Gui, ShowTip: +LastFound +AlwaysOnTop +ToolWindow -Caption +E0x08000020 | |
Gui, ShowTip: Color, FFFFF0 | |
WinSet, TransColor, FFFFF0 150 | |
Gui, ShowTip: Margin, 10, 5 | |
Gui, ShowTip: Font, Q3 s20 bold | |
Gui, ShowTip: Add, Text,, %s% | |
Gui, ShowTip: Show, NA %pos%, ShowTip | |
SetTimer, ShowTip_ChangeColor, 1000 | |
ShowTip_ChangeColor: | |
Gui, ShowTip: +AlwaysOnTop | |
r:=StrSplit(SubStr(bak,1,InStr(bak,",")-1),"|") | |
Gui, ShowTip: Font, % "Q3 c" r[idx:=Mod(Round(idx),r.length())+1] | |
GuiControl, ShowTip: Font, Static1 | |
return | |
} | |
;============ Hotkey ============= | |
F1:: | |
Suspend, Permit | |
Goto, RecordScreen | |
F2:: | |
Suspend, Permit | |
Goto, RecordWindow | |
RecordScreen: | |
RecordWindow: | |
if (Recording or Playing) | |
return | |
Coord:=InStr(A_ThisLabel,"Win") ? "Window":"Screen" | |
LogArr:=[], oldid:="", Log(), Recording:=1, SetHotkey(1) | |
ShowTip("Recording") | |
return | |
F3:: | |
Stop: | |
Suspend, Permit | |
if Recording | |
{ | |
if (LogArr.MaxIndex()>0) | |
{ | |
s:="`nLoop, 1`n{`n`nSetTitleMatchMode, 2" | |
. "`nCoordMode, Mouse, " Coord "`n" | |
For k,v in LogArr | |
s.="`n" v "`n" | |
s.="`nSleep, 1000`n`n}`n" | |
s:=RegExReplace(s,"\R","`n") | |
FileDelete, %LogFile% | |
FileAppend, %s%, %LogFile% | |
s:="" | |
} | |
SetHotkey(0), Recording:=0, LogArr:="" | |
} | |
else if Playing | |
{ | |
WinGet, list, List, %Play_Title% | |
Loop, % list | |
if WinExist("ahk_id " list%A_Index%)!=A_ScriptHwnd | |
{ | |
WinGet, pid, PID | |
WinClose,,, 3 | |
IfWinExist | |
Process, Close, %pid% | |
} | |
SetTimer, CheckPlay, Off | |
Playing:=0 | |
} | |
ShowTip() | |
Suspend, Off | |
Pause, Off | |
GuiControl,, Pause, % "[F6] Pause " | |
isPaused:=0 | |
return | |
F4:: | |
Play: | |
Suspend, Permit | |
if (Recording or Playing) | |
Gosub, Stop | |
ahk:=A_IsCompiled ? A_ScriptDir "\AutoHotkey.exe" : A_AhkPath | |
IfNotExist, %ahk% | |
{ | |
MsgBox, 4096, Error, Can't Find %ahk% ! | |
Exit | |
} | |
Run, %ahk% /r "%LogFile%" | |
SetTimer, CheckPlay, 500 | |
Gosub, CheckPlay | |
return | |
CheckPlay: | |
Check_OK:=0 | |
WinGet, list, List, %Play_Title% | |
Loop, % list | |
if (list%A_Index%!=A_ScriptHwnd) | |
Check_OK:=1 | |
if Check_OK | |
Playing:=1, ShowTip("Playing") | |
else if Playing | |
{ | |
SetTimer, CheckPlay, Off | |
Playing:=0, ShowTip() | |
} | |
return | |
F5:: | |
Edit: | |
Suspend, Permit | |
Gosub, Stop | |
Run, notepad.exe "%LogFile%" | |
return | |
F6:: | |
Pause: | |
Suspend, Permit | |
if Recording | |
{ | |
Suspend | |
Pause, % A_IsSuspended ? "On":"Off", 1 | |
isPaused:=A_IsSuspended, Log() | |
} | |
else if Playing | |
{ | |
isPaused:=!isPaused | |
WinGet, list, List, %Play_Title% | |
Loop, %list% | |
if WinExist("ahk_id " list%A_Index%)!=A_ScriptHwnd | |
PostMessage, 0x111, 65306 | |
} | |
else return | |
if isPaused | |
GuiControl,, Pause, [F6]<Pause> | |
else | |
GuiControl,, Pause, % "[F6] Pause " | |
return | |
;============ Functions ============= | |
SetHotkey(f:=0) { | |
; These keys are already used as hotkeys | |
global UsedKeys | |
f:=f ? "On":"Off" | |
Loop, 254 | |
{ | |
k:=GetKeyName(vk:=Format("vk{:X}", A_Index)) | |
if k not in ,Control,Alt,Shift,%UsedKeys% | |
Hotkey, ~*%vk%, LogKey, %f% UseErrorLevel | |
} | |
For i,k in StrSplit("NumpadEnter|Home|End|PgUp" | |
. "|PgDn|Left|Right|Up|Down|Delete|Insert", "|") | |
{ | |
sc:=Format("sc{:03X}", GetKeySC(k)) | |
if k not in ,Control,Alt,Shift,%UsedKeys% | |
Hotkey, ~*%sc%, LogKey, %f% UseErrorLevel | |
} | |
SetTimer, LogWindow, %f% | |
if (f="On") | |
Gosub, LogWindow | |
} | |
LogKey: | |
LogKey() | |
return | |
LogWindow: | |
LogWindow() | |
return | |
LogKey() { | |
Critical | |
k:=GetKeyName(vksc:=SubStr(A_ThisHotkey,3)) | |
k:=StrReplace(k,"Control","Ctrl"), r:=SubStr(k,2) | |
if r in Alt,Ctrl,Shift,Win | |
LogKey_Control(k) | |
else if k in LButton,RButton,MButton | |
LogKey_Mouse(k) | |
else | |
{ | |
if (k="NumpadLeft" or k="NumpadRight") and !GetKeyState(k,"P") | |
return | |
k:=StrLen(k)>1 ? "{" k "}" : k~="\w" ? k : "{" vksc "}" | |
Log(k,1) | |
} | |
} | |
LogKey_Control(key) { | |
global LogArr, Coord | |
k:=InStr(key,"Win") ? key : SubStr(key,2) | |
if (k="Ctrl") | |
{ | |
CoordMode, Mouse, %Coord% | |
MouseGetPos, X, Y | |
} | |
Log("{" k " Down}",1) | |
Critical, Off | |
KeyWait, %key% | |
Critical | |
Log("{" k " Up}",1) | |
if (k="Ctrl") | |
{ | |
i:=LogArr.MaxIndex(), r:=LogArr[i] | |
if InStr(r,"{Blind}{Ctrl Down}{Ctrl Up}") | |
LogArr[i]:="MouseMove, " X ", " Y | |
} | |
} | |
LogKey_Mouse(key) { | |
global gui_id, LogArr, Coord | |
k:=SubStr(key,1,1) | |
CoordMode, Mouse, %Coord% | |
MouseGetPos, X, Y, id | |
if (id=gui_id) | |
return | |
Log("MouseClick, " k ", " X ", " Y ",,, D") | |
CoordMode, Mouse, Screen | |
MouseGetPos, X1, Y1 | |
t1:=A_TickCount | |
Critical, Off | |
KeyWait, %key% | |
Critical | |
t2:=A_TickCount | |
if (t2-t1<=200) | |
X2:=X1, Y2:=Y1 | |
else | |
MouseGetPos, X2, Y2 | |
i:=LogArr.MaxIndex(), r:=LogArr[i] | |
if InStr(r, ",,, D") and Abs(X2-X1)+Abs(Y2-Y1)<5 | |
LogArr[i]:=SubStr(r,1,-5), Log() | |
else | |
Log("MouseClick, " k ", " (X+X2-X1) ", " (Y+Y2-Y1) ",,, U") | |
} | |
LogWindow() { | |
global oldid, LogArr | |
static oldtitle | |
id:=WinExist("A") | |
WinGetTitle, title | |
WinGetClass, class | |
if (title="" and class="") | |
return | |
if (id=oldid and title=oldtitle) | |
return | |
oldid:=id, oldtitle:=title | |
title:=SubStr(title,1,50) | |
if (!A_IsUnicode) | |
{ | |
GuiControl,, MyText, %title% | |
GuiControlGet, s,, MyText | |
if (s!=title) | |
title:=SubStr(title,1,-1) | |
} | |
title.=class ? " ahk_class " class : "" | |
title:=RegExReplace(Trim(title), "[``%;]", "``$0") | |
s:="tt = " title "`nWinWait, %tt%" | |
. "`nIfWinNotActive, %tt%,, WinActivate, %tt%" | |
i:=LogArr.MaxIndex(), r:=LogArr[i] | |
if InStr(r,"tt = ")=1 | |
LogArr[i]:=s, Log() | |
else | |
Log(s) | |
} | |
Log(str:="", Keyboard:=0) { | |
global LogArr | |
static LastTime | |
t:=A_TickCount, Delay:=(LastTime ? t-LastTime:0), LastTime:=t | |
IfEqual, str,, return | |
i:=LogArr.MaxIndex(), r:=LogArr[i] | |
if (Keyboard and InStr(r,"Send,") and Delay<1000) | |
{ | |
LogArr[i]:=r . str | |
return | |
} | |
if (Delay>200) | |
LogArr.Push("Sleep, " (Delay//2)) | |
LogArr.Push(Keyboard ? "Send, {Blind}" str : str) | |
} | |
;============ The End ============ | |
; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment