Advertisement
pk3456

ahk macro recorder

Apr 30th, 2023 (edited)
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. $+F13:: {
  2.     ; toggle macro recording with the specified name
  3.     MacroRecorder.Toggle("M1.ahk")
  4. }
  5.  
  6. F2:: {
  7.     Run "M1.ahk"
  8. }
  9.  
  10. class MacroRecorder {
  11.     static __New() {
  12.         ih := this.KeyHook := InputHook("V")
  13.         ih.KeyOpt("{All}", "N")
  14.         ih.DownKeys := Map()
  15.         ih.TimeSincePriorKey := 0
  16.         ih.OnKeyDown := ObjBindMethod(this, "OnKeyDown")
  17.         ih.OnKeyUp := ObjBindMethod(this, "OnKeyUp")
  18.     }
  19.  
  20.     static Toggle(FileName?) {
  21.         HotKeyWait() ; wait for hotkey to release
  22.  
  23.         ih := this.KeyHook
  24.         IsSet(FileName) && this.FileName := FileName ; if filename variable exist, create this.FileName property
  25.         if ih.InProgress {
  26.             ih.Stop()
  27.             this.Save()
  28.             ToolTip "Recording stopped"
  29.             SetTimer ToolTip, -1500
  30.         } else {
  31.             ih.TimeSincePriorKey := 0
  32.             this.TempStore := "#Requires AutoHotkey v2.0`n"
  33.             ih.Start()
  34.             ToolTip "Recording started"
  35.         }
  36.  
  37.         return ih.InProgress ; returns true if inputhook is started
  38.     }
  39.  
  40.     static Save(*) {
  41.         saveFile := this.FileName
  42.         if this.KeyHook.InProgress
  43.             this.Toggle()
  44.  
  45.         fileObj := FileOpen(saveFile, "w`n")
  46.         fileObj.Write(this.TrimOutput())
  47.         fileObj.Close()
  48.     }
  49.  
  50.     static TrimOutput() {
  51.         if A_ThisHotkey {
  52.             temp := this.TempStore
  53.             line := StrLen(temp)
  54.             loop parse A_ThisHotkey {
  55.                 switch A_LoopField {
  56.                     ; find the position of the first hotkey prefix pressed
  57.                     case "^": line := Min(InStr(temp, "Control Down",, -1), line)
  58.                     case "!": line := Min(InStr(temp, "Alt Down",, -1), line)
  59.                     case "+": line := Min(InStr(temp, "Shift Down",, -1), line)
  60.                     case "#": line := Min(InStr(temp, "Win Down",, -1), line)
  61.                 }
  62.             }
  63.             temp := SubStr(temp, 1, line)
  64.             temp := RegExReplace(temp, "(Sleep\(\d+\)\R)?Send.*\Z") ; remove the last sleep and the last found Send prefix
  65.         }
  66.         return temp
  67.     }
  68.  
  69.     static OnKeyDown(ih, VK, SC) {
  70.         elapsedTime := A_TickCount - (ih.TimeSincePriorKey || A_TickCount)
  71.         ih.TimeSincePriorKey := A_TickCount
  72.         key := GetKeyName(Format("vk{:x}sc{:x}", VK, SC))
  73.         if ih.DownKeys.Get(key, "") ; prevent auto-repeat
  74.             return
  75.         ih.DownKeys.Set(key, 1)
  76.  
  77.         Text := ""
  78.         if elapsedTime
  79.             Text .= "Sleep(" elapsedTime ")`n"
  80.         Text .= 'Send("{' key ' Down}")`n'
  81.         ToolTip Text
  82.  
  83.         this.TempStore .= Text
  84.     }
  85.  
  86.     static OnKeyUp(ih, VK, SC) {
  87.         elapsedTime := A_TickCount - (ih.TimeSincePriorKey || A_TickCount)
  88.         ih.TimeSincePriorKey := A_TickCount
  89.         key := GetKeyName(Format("vk{:x}sc{:x}", VK, SC))
  90.         ih.DownKeys.Has(key) && ih.DownKeys.Delete(key)
  91.  
  92.         Text := ""
  93.         if elapsedTime
  94.             Text .= "Sleep(" elapsedTime ")`n"
  95.         Text .= 'Send("{' key ' Up}")`n'
  96.  
  97.         this.TempStore .= Text
  98.     }
  99. }
  100.  
  101. ; wait for all keys in the hotkey to release
  102. HotKeyWait() {
  103.     if !A_ThisHotkey
  104.         return
  105.     RegExMatch(A_ThisHotkey, "i)(?:([$~*<>!^#+]+)|(?:(\S+) +& +))?(\S+)", &M)
  106.     keys := []
  107.     if M[1] { ; get prefix symbols
  108.         index := 1
  109.         loop StrLen(M[1]) {
  110.             str := SubStr(M[1], index++, 1)
  111.             LR := ""
  112.             (str = "<") && LR := "L"
  113.             (str = ">") && LR := "R"
  114.             switch LR ? SubStr(M[1], index++, 1) : str {
  115.                 case "!": keys.Push(LR "Alt")
  116.                 case "^": keys.Push(LR "Ctrl")
  117.                 case "+": keys.Push(LR "Shift")
  118.                 case "#": keys.Push((LR||"L") "Win")
  119.             }
  120.         }
  121.     } else if M[2] { ; get custom prefix if any
  122.         keys.Push(M[2])
  123.     }
  124.     keys.Push(M[3]) ; get the rest of the hotkey
  125.     for k in keys {
  126.         KeyWait k
  127.     }
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement