[Tool] Macro Commander v3.0

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

[Tool] Macro Commander v3.0

09 Feb 2019, 17:01

Hello,
The script below allows you to execute macro commands with a combination of letters. 8-)
Simple macros can be encoded more quickly thanks to the simplified syntax. :)
(1 letter = 1 keyboard command) see letters below :geek:

It is not a macro recorder and not an AHK editor !!
Even if you can grabe a few mouse clicks, you still have to enter keyboard commands manually. :mrgreen:

Any suggestions to improve the code are welcome.

Here is the code:

Code: Select all

; =================================================================================================================================
; Name:           MACRO COMMANDER 
; Description:    Execute macro commands with a combination of letters
; Topic:          https://www.autohotkey.com/boards/viewtopic.php?f=6&t=61904          
; Sript version:  3.0
; AHK Version:    1.1.24.03 (A32/U32/U64)
; Tested on:      Win 7 (x64)
; Author:         SpeedMaster

; How to play:     Add a line that begin with " : " to  insert a keyboard command
;                  Each letter represents a key command
;                  for example
;                  :U2D{F2}L4SE    =   Send, {Up 2}{Down}{F2}{Left 4} (Sleep, 1000) {Enter}
;                  2 consecutive left clicks at the same position will be interpreted as a double-click
; ==================================================================================================================================
version:="3.0"

#SingleInstance, force
coordmode, mouse, screen
SetWorkingDir %A_ScriptDir%

help=
(
Win + F12 = Hide Show Gui
Win + F11 = Play the macro
Win + Space = insert a left click.
Win + X = insert a right click.
2 clicks at the same position  =  double-click
Win + W = insert current window title as comment
Win + C = insert a Wait For Color
Win + Esc = exit the script

Add a line that begin with " : " to  insert a keyboard command
or " :$ " to loop for ex. (:$7ud = send up down 7 times )
(see command letters tab below)
)

Gui 1: +Resize +AlwaysOnTop 
Gui 1: -dpiscale
Gui 1: font, s10
Gui 1: Add, Text,, % help
gui 1: font
Gui 1: Add, Text,, Delay between clicks in ms
Gui 1: Add, Edit, veditdelay disabled
Gui 1: Add, UpDown, vDelayTimer Range100-100000, 500
Gui 1: +Resize 

Gui 1: Add, CheckBox, x+20 yp+2 hp-25 -border gtoggleLoopPlay vLoopPlay, Repeat
Gui 1: Add, Edit,  x+1 yp-3 w80 +Number ved_rep Disabled c5D69BA,
Gui 1: Add, UpDown, vrepeat x34  Range1-999999, 2
Gui 1: Add, CheckBox, x+15 yp+2 hp-25 -border gnohide vNohide, Show Gui
Gui 1: Add, progress, xm y+10 w19 h19 vcapture
Gui 1: Add, text, xp-1 yp-1 wp+2 hp+2 backgroundtrans border,x
Gui 1: Add, text, x+4 yp+4, Wait For Color ( #C )
Gui 1: Add, button, x+20 yp-2 hp-25  gresetonce, Reset Run and SleepOnce
Gui 1: Add, text, x+4 yp hp vResetState 0x201, 0

Gui 1: Add, tab3, x10 section vmytab, Macro|Transcriber|Command Letters
gui 1: font, s12
Gui 1: Add, Edit, y+30 w350 h300 -ReadOnly vmyedit -Wrap HScroll WantTab hwndHandle
Gui 1: font
Gui 1: Add, Button, Default vbtplay yp-27, PLAY
Gui 1: Add, Button, x+10, CLEAR
Gui 1: Add, Button, x+25, LOAD
Gui 1: Add, Button, x+10, SAVE
gui 1:tab, Transcriber
Gui 1: Add, Edit, y+30 w350 h300  vmyedit2 -Wrap HScroll WantTab
Gui 1: Add, Button, xm+10 yp-27 gtranscribetoahk, Transcribe to AHK syntax
Gui 1: Add, Button, x+10 yp ginsertmousedelays, Insert Mouse Delays
Gui 1: Add, Button, x+10 yp gcopytoclipboard, Copy to clipboard
gui 1:tab, Command Letters
Gui 1: Add, Edit, w350 h320 ReadOnly vmyedit3 -Wrap HScroll WantTab
gosub, commandlist
guicontrol,, myedit3, % list
Gui 1: show, w400 h645, %  "Macro Commander v" . version
toggle:=1, clickscount:=0
guicontrol, enable, editdelay
Gui 1: Submit, nohide
SetTimer, GetColor, 50, ON
; Hide Show Gui
#F12:: 

loopplay:=0
guicontrol,, loopplay, 0
GuiControl,disable,ed_rep

toggle:=!toggle
        if toggle {
        Gui 1: Show, w400 h645, % "Macro Commander v" . version
        GuiControl, Focus, MyEdit
        SendMessage, 0xB1, -2, -1,, ahk_id %Handle%
        SendMessage, 0xB7,,,, ahk_id %Handle%
        }
        else
        gui 1: hide
return

GuiSize:
	If (A_EventInfo = 1) ; The window has been minimized.
		Return
	AutoXYWH("wh", "mytab")
	AutoXYWH("wh", "myedit", "myedit2" ,"myedit3")
return

nohide:
Nohide:=!Nohide
return


; Play Macro
#F11::
        gosub, buttonplay
return

; Insert Left Click
#space::
        Gui 1: Submit, NoHide
        MouseGetPos, xpos, ypos, 
        tooltip, % ++clickscount ": " xpos " " ypos
        myedit .= "`n" . "mouseclick, left, " xpos  " ," ypos 
        guicontrol,, myedit, % myedit
        SendMessage, 0xB1, -2, -1,, ahk_id %Handle%
        SendMessage, 0xB7,,,, ahk_id %Handle%
        sleep, 300
        tooltip,
return

; Insert Right Click
#x::
        Gui 1: Submit, NoHide
        MouseGetPos, xpos, ypos, 
        tooltip, % ++clickscount ": " xpos " " ypos
        myedit .= "`n" . "mouseclick, right, " xpos  " ," ypos 
        guicontrol,, myedit, % myedit
        SendMessage, 0xB1, -2, -1,, ahk_id %Handle%
        SendMessage, 0xB7,,,, ahk_id %Handle%  
        sleep, 300
        tooltip,
return

; Insert Window Title as comment
#w::
        Gui 1: Submit, NoHide
        WinGetTitle, Title, A        
        myedit .="`n; " . Title
        guicontrol,, myedit, % myedit
        SendMessage, 0xB1, -2, -1,, ahk_id %Handle%
        SendMessage, 0xB7,,,, ahk_id %Handle%          
        tooltip, % Title
        sleep, 300
        tooltip,        
return

; Insert Wait for color
#c::
        Gui 1: Submit, NoHide
        gosub, getcolor
        myedit .= "`n" . "WaitForColor, " color ", " MouseX  ", " MouseY ", true"
        guicontrol,, myedit, % myedit
        SendMessage, 0xB1, -2, -1,, ahk_id %Handle%
        SendMessage, 0xB7,,,, ahk_id %Handle%  
        sleep, 300
        tooltip,
return

GetColor:
        coordmode, pixel
    MouseGetPos, MouseX, MouseY
    PixelGetColor, Color, % MouseX, % MouseY, RGB
    GuiControl, % "+background" SubStr(Color, 3) , capture
return	


toggleLoopPlay:

if (LoopPlay:=!LoopPlay)
 {
  guicontrol,, loopplay, 1
  GuiControl,enable,ed_rep
 }
else
 {
  guicontrol,, loopplay, 0
  GuiControl,enable0,ed_rep
 }
return


Resetonce:
runonce:=sleeponce:=ActivateRunonce:=ActivateSleepOnce:=""
guicontrol,, resetstate, 0
return


ButtonPLAY:
Gui 1: Submit
clickscount:=0

GuiControlGet,ed_rep,,repeat


runmacro:

if !ed_rep
ed_rep:=1

if !LoopPlay
ed_rep:=1

Loop % ed_rep
{
loop, parse, myedit, `n 
{

        if regexmatch(a_loopfield, "mouseclick,.*(l|r)\D+(\d+)\D+(\d+)",match) {
                MouseMove, match2, match3
                tooltip, % ++clickscount                
                if !(pmatch2==match2) && !(pmatch3==match3)
                Sleep, % DelayTimer
                mouseclick, % (match1="r") ? "right" : "left"
        }
        pmatch2:=match2, pmatch3:=match3

        if regexmatch(a_loopfield, "^msgbox,") {
                msg_:=regexreplace(a_loopfield, "msgbox,( )?")
                MsgBox, % msg_
                msg_:=""
        }

        if regexmatch(a_loopfield, "^run,") {
                runprog:=regexreplace(a_loopfield, "run,( )?")
                run, % runprog
        }

        if regexmatch(a_loopfield, "^runonce,") && !runonce {
                runprog:=regexreplace(a_loopfield, "runonce,( )?")
                run, % runprog
                ActivateRunonce:=1
                runprog:=""
        }

        if regexmatch(a_loopfield, "^sleeponce,") && !sleeponce {
                sleeponcetime:=regexreplace(a_loopfield, "sleeponce,( )?")
                sleep, % (sleeponcetime) ? sleeponcetime : "1000"
                ActivateSleeponce:=1
                sleeponcetime:=""
        }


        if instr(a_loopfield, "waitforcolor") {
                Color_m:=""
                pcolor:=strsplit(a_loopfield, "`,")
                CoordMode Pixel
                tooltip, waiting for color
                if regexmatch(pcolor.5, "( )+?(f|0)")
                Loop 
                    {   
                       PixelGetColor, color_m, pcolor.3, pcolor.4, RGB
                    } Until (Color_m != pcolor.2)
                else
                Loop 
                    {   
                       PixelGetColor, color_m, pcolor.3, pcolor.4, RGB
                    } Until (Color_m = pcolor.2) 
                tooltip
        }

        if regexmatch(a_loopfield, "^:") {
                match_l:=""
                if regexmatch(a_loopfield, "^:\$") {
                        regexmatch(substr(a_loopfield, 2), "i)(^\$)(?! *)?([0-9]*\.[0-9]+|[0-9]+)",match_l)
                        match_l:=substr(match_l, 2)
                        
                }
                loop, % (match_l) ? (match_l) : 1
                {                   
                sendstring:=0, toggleshift:=0
                for k, v in strsplit(a_loopfield) {
                        if (ctn) {
                                --ctn
                               continue
                        }
                        if (v="""") && (ztr)
                        sendstring := !sendstring
        
                        if !(sendstring)  {
                                if (v=";") {
                                        break
                                }
                                if (v="s") {
                                match_s:=""
                                regexmatch(substr(a_loopfield, k), "i)(^s)(?! *)?([0-9]*\.[0-9]+|[0-9]+)",match_s)
                                        if (match_s) {
                                                match_s:=substr(match_s, 2)
                                                tooltip, % "Sleep " match_s " sec"
                                                sleep, % round((1000 * match_s))
                                        }
                                        else {
                                                tooltip, % "Sleep 1 sec"
                                                sleep, 1000
                                        }
                                        tooltip,
                                }

                                if (v="f") && !(sendkey) {
                                match_f:=""
                                regexmatch(substr(a_loopfield, k), "i)(^f)(?! *)?([0-9]+)",match_f)
                                        if (match_f) {
                                                match_f:=substr(match_f, 2)
                                                SendInput, {F%match_f%}
                                        }
                                        else {
                                                Send, ^f
                                        }
                                }


                                else if (v="i") && !(sendkey) {
                                        clip:=clipboard, num:=lnum:=tn:=nd:=t:=d:=""
                                        RegExMatch(clip, ".*(?:\D|^)(\d+)" , tn), RegExMatch(clip, "(\d+)\D*\z" , nd), RegExMatch(tn, "(\d+)\D*\z" , num)
                                        StringLen, lnum, num
                                        if num is integer
                                        ++num
                                        SetFormat, Float, 0%lnum%
                                        num += 0.0
                                        StringTrimRight, t, tn, %lnum% 
                                        StringTrimLeft , d, nd, %lnum%
                                        clip:= t . num . d 
                                        (num) && clipboard:=Clip
                                        sleep, 100
                                        clip:=num:=lnum:=tn:=nd:=t:=d:=""
                                }                                   

								else if (v="{") {
										sendkey:=1, match_k:=""
										regexmatch(substr(a_loopfield, k), "^{.*?}",match_k)
										SendInput, % match_k
									}
								else if (v="}") && (sendkey)
										sendkey:=0

 								else if (v="(") {
                                 match_command:=""
                                 ;msgbox, % substr(a_loopfield, k)
                                 regexmatch(substr(a_loopfield, k), "(?<=\()(?:[^()]+|\([^)]+\))+(?=\))", match_command)
                                         if (match_command) {
                                                 ;msgbox, % match_command
                                                 sendraw, % match_command
                                                         ctn:=strlen(match_command)+1
                                                         match_command:=""
                                         }										
 									}
 
                                else if (v="u") && !(sendkey)
                                        sk("u", "UP")    
                                else if (v="d") && !(sendkey)
                                        sk("d", "Down")
                                else if (v="l") && !(sendkey)
                                        sk("l", "Left")  
                                else if (v="r") && !(sendkey)
                                        sk("r", "Right")   
                                else if (v="e") && !(sendkey)
                                        sk("e", "Enter") 
                                else if (v="t") && !(sendkey)
                                        sk("t", "Tab") 
                                else if (v="k") && !(sendkey)
                                        sk("k", "Appskey")										
                                else if (v="h") && !(sendkey)
                                        sk("h", "Home")   
                                else if (v="n") && !(sendkey)
                                        sk("n", "End")
                                else if (v="b") && !(sendkey)
                                        sk("b", "BackSpace") 
                                else if (v="c") && !(sendkey)
                                Send, ^c 
                                else if (v="v") && !(sendkey)
                                Send, ^v   
                                else if (v="x") && !(sendkey)
                                Send, ^x  
                                else if (v="a") && !(sendkey)
                                Send, ^a
                                else if (v="q") && !(sendkey)
                                Send, !{f4}  
                                else if (v="w") && !(sendkey)
                                Clipwait, 2  
                                else if (v="z") && !(sendkey)
                                Clipboard:=""    
                                else if (v="p") && !(sendkey)
                                clipboard = %clipboard%                                   
                                else if (v="m") && !(sendkey)
                                msgbox, 

                                
                                else if (v="+") {
                                        toggleshift:=!toggleshift 
                                        if (toggleshift)
                                                send, {Shift down}
                                        else
                                                send, {Shift up} 
                                } 
                                else if (v="^") {
                                        toggleControl:=!toggleControl 
                                        if (toggleControl)
                                                send, {Ctrl down}
                                        else
                                                send, {Ctrl up} 
                                } 
                                else if (v="!") {
                                        toggleAlt:=!toggleAlt 
                                        if (toggleAlt)
                                                send, {Alt down}
                                        else
                                                send, {Alt up} 
                                }  
                                else if (v="#") {
                                        toggleWin:=!toggleWin 
                                        if (toggleWin)
                                                send, {LWin down}
                                        else
                                                send, {LWin up} 
                                }                                 

                        }

                        if (sendstring) {
                                if !(v="""")
                                tosend .= v
                        }     

                        if !(sendstring) && (tosend!="") {
                                sendraw, % tosend
                                tosend:=""
                        }
                } ; end of for loop (to parse a command line)
        }  ; end of if command ":"
                } ; end of loop current command line (:$(n) parameter for ex. :$25 = loop this line 25 times          


        ; Ensure that all toggle keys are released
        if (toggleShift) {
                send, {Shift up}        
                toggleShift:=0
        }        
        if (toggleControl) {
                send, {Ctrl up}        
                toggleControl:=0
        }
        if (toggleAlt) {
                send, {Alt up}        
                toggleAlt:=0
        }
        if (toggleWin) {
                send, {Lwin up}        
                toggleWin:=0
        } 
        
        
} ;end of parse lines loop


clickscount:=0

(ActivateRunonce) && runonce:=1
(ActivateSleepOnce) && sleeponce:=1
if (runonce=1 || sleeponce=1) {
        guicontrol,, resetstate, 1
}
 
tooltip, % "done :  " a_index "/" ed_rep
sleep, 400
tooltip,

if !loopplay
    break  

} ; end of repeat the macro

if nohide {
        gui 1: show
        toggle:=1
}   
else
{
        gui 1: hide 
        toggle:=0
}
return


guiclose:
toggle:=""
gui 1: hide
return

copytoclipboard:
gui, submit, nohide
clipboard:=myedit2
return


insertmousedelays:
gui, submit, nohide
outwithmousedelay:=""
loop, parse, text_out, "`n", "`r"
	if instr(a_loopfield, "mouseclick")
		outwithmousedelay .= a_loopfield "`n" "sleep, " DelayTimer "`n"
	else
		outwithmousedelay .= a_loopfield  "`n"

guicontrol,, myedit2, %  remove_delay_between_same_clicks(outwithmousedelay)


remove_delay_between_same_clicks(var) {
tesa:=strsplit(var, "`n", "`r")
tesb:=tesa.clone()
for k, v in tesa
	if regexmatch(v, "^mouseclick.*",m) {
		regexmatch(tesa[k+2], "^mouseclick.*",n)
		if (n=m)
			tesb[k+1]:="erasemmme"
	}
for k, v in tesb
    if instr(v, "erasemmme")
		tesb.removeat(k)
return st_glue(tesb)
}
return

TranscribetoAHK:
text_out:=""
guicontrolget, text_in,,myedit
loop, parse, text_in, `n 
{
        if !(regexmatch(a_loopfield, "^:")) {
			curtline:=a_loopfield
			if instr(curtline, "waitforcolor") {
				pcolor:=strsplit(curtline, "`,")
				curtline :="`nCoordMode Pixel`nLoop`n{`n   PixelGetColor, color, " pcolor.3 ", " pcolor.4 ", RGB`n} Until (Color = " pcolor.2 ")" 
			}
			text_out .= "`n" . curtline
		}
        if regexmatch(a_loopfield, "^:") {

                match_l_debug:=""
                if regexmatch(a_loopfield, "^:\$") {
                        regexmatch(substr(a_loopfield, 2), "i)(^\$)(?! *)?([0-9]*\.[0-9]+|[0-9]+)",match_l_debug)
                        match_l_debug:=substr(match_l_debug, 2)                       
                }
                if (match_l_debug) {
                        text_out .= "`nLoop, " match_l_debug " {`n"
                        closeloop:=1
                }


                sendstringdebug:=0, toggleshiftdeb:=0
                for k, v in strsplit(a_loopfield) {
                        if (ctn_deb) {
                                --ctn_deb
                               continue
                        }
                        if (v="""") && (ztr_deb)
                        sendstringdebug := !sendstringdebug
                        if !(sendstringdebug) {
                                 if (v=";") {
                                        break
                                }                               
                                if (v="s") {
                                match_s_debug:=""
                                regexmatch(substr(a_loopfield, k), "i)(^s)(?! *)?([0-9]*\.[0-9]+|[0-9]+)",match_s_debug)
                                        if (match_s_debug) {
                                                match_s_debug:=substr(match_s_debug, 2)
                                                text_out .= "`nsleep, "  round((1000 * match_s_debug))
                                        }
                                        else 
                                                text_out .= "`nsleep, 1000"
                                }

                                if (v="f") && !(sendkey_debug) {
                                match_f_debug:=""
                                regexmatch(substr(a_loopfield, k), "i)(^f)(?! *)?([0-9]+)",match_f_debug)
                                        if (match_f_debug) {
                                                match_f_debug:=substr(match_f_debug, 2)
												text_out .= "`nSendInput, {F" match_f_debug "}"
                                        }
                                        else {
                                                text_out .= "`nSend, ^f"
                                        }
                                }

                                else if (v="i") {
                                        
txtapp=
(%
clip:=clipboard, num:=lnum:=tn:=nd:=t:=d:=""
RegExMatch(clip, ".*(?:\D|^)(\d+)" , tn), RegExMatch(clip, "(\d+)\D*\z" , nd), RegExMatch(tn, "(\d+)\D*\z" , num)
StringLen, lnum, num
if num is integer
++num
SetFormat, Float, 0%lnum%
num += 0.0
StringTrimRight, t, tn, %lnum% 
StringTrimLeft , d, nd, %lnum%
clip:= t . num . d 
(num) && clipboard:=Clip
sleep, 100
clip:=num:=lnum:=tn:=nd:=t:=d:=""                                        
)                             
                                        text_out .= "`n" txtapp                                     
                                        txtapp:=""
                                }

								else if (v="{") {
										sendkey_debug:=1, match_k_debug:=""
										regexmatch(substr(a_loopfield, k), "^{.*?}",match_k_debug)
										text_out .= "`nSendInput, " . match_k_debug
									}
								else if (v="}") && (sendkey_debug)
										sendkey_debug:=0

 								else if (v="(") {
                                 match_command_deb:=""
                                 regexmatch(substr(a_loopfield, k), "(?<=\()(?:[^()]+|\([^)]+\))+(?=\))", match_command_deb)
                                         if (match_command_deb) {
                                                text_out .= "`nSendRaw, " match_command_deb
                                                         ctn_deb:=strlen(match_command_deb)+1
                                                         match_command_deb:=""
                                         }										
 									}

                                else if (v="u") && !(sendkey_debug)
                                        sk_debug("u","Up")
                                else if (v="d") && !(sendkey_debug)
                                        sk_debug("d","Down")
                                else if (v="l") && !(sendkey_debug)
                                        sk_debug("l","Left")
                                else if (v="r") && !(sendkey_debug)
                                        sk_debug("r","Right")    
                                else if (v="e") && !(sendkey_debug)
                                        sk_debug("e","Enter")  
                                else if (v="t") && !(sendkey_debug)
                                        sk_debug("t","Tab")
                                else if (v="k") && !(sendkey_debug)
                                        sk_debug("k","Appskey")										
                                else if (v="h") && !(sendkey_debug)
                                        sk_debug("h","Home")  
                                else if (v="n") && !(sendkey_debug)
                                        sk_debug("n","End") 
                                else if (v="b") && !(sendkey_debug)
                                        sk_debug("b","BackSpace")  
                                else if (v="c") && !(sendkey_debug)
                                text_out .= "`nSend, ^c" 
                                else if (v="v") && !(sendkey_debug)
                                text_out .= "`nSend, ^v"   
                                else if (v="x") && !(sendkey_debug)
                                text_out .= "`nSend, ^x"  
                                else if (v="a") && !(sendkey_debug)
                                text_out .= "`nSend, ^a"
                                else if (v="q") && !(sendkey_debug)
                                text_out .= "`nSend, !{f4}"  
                                else if (v="w") && !(sendkey_debug)
                                text_out .= "`nClipWait"
                                else if (v="z") && !(sendkey_debug)
                                text_out .= "`nClipboard=" 
                                else if (v="p") && !(sendkey_debug)
                                text_out .= "`nClipboard = %clipboard%"                               
                                else if (v="m") && !(sendkey_debug)
                                text_out .= "`nMsgbox,"									
                                
                                else if (v="+") && !(sendkey_debug) {
                                        toggleshiftdebug:=!toggleshiftdebug
                                        if (toggleshiftdebug)
                                                text_out .= "`nSend, {Shift down}"
                                        else
                                                text_out .= "`nSend, {Shift up}" 
                                } 
                                else if (v="^") {
                                        toggleControldebug:=!toggleControldebug
                                        if (toggleControldebug)
                                                text_out .= "`nSend, {Ctrl down}"
                                        else
                                                text_out .= "`nSend, {Ctrl up}" 
                                }
                                else if (v="!") {
                                        toggleAltdebug:=!toggleAltdebug
                                        if (toggleAltdebug)
                                                text_out .= "`nSend, {Alt down}"
                                        else
                                                text_out .= "`nSend, {Alt up}" 
                                }
                                else if (v="#") {
                                        toggleWindebug:=!toggleWinDebug 
                                        if (toggleWinDebug)
                                                text_out .= "`nSend, {LWin down}"
                                        else
                                                text_out .= "`nSend, {LWin up}"
                                }                                
              
                        }
                        
                        if (sendstringdebug) {
                                if !(v="""")
                                tosenddebug .= v
                        }     

                        if !(sendstringdebug) && (tosenddebug!="") {
                                text_out .= "`nSendRaw, "  tosenddebug
                                tosenddebug:=""
                        }                        
                }
        }


        ; Ensure that all toggle keys are released

        if (toggleshiftdebug) {
                text_out .= "`nsend, {Shift up} `; Don't forget to put a second   +  to release the key "        
                toggleshiftdebug:=0
        } 
        if (toggleControldebug) {
                text_out .= "`nsend, {Ctrl up} `; Don't forget to put a second   ^   to release the key "        
                toggleControldebug:=0
        }
        if (toggleAltdebug) {
                text_out .= "`nsend, {Alt up} `; Don't forget to put a second   !   to release the key "        
                toggleAltdebug:=0
        }
        if (toggleWindebug) {
                text_out .= "`nsend, {Lwin up} `; Don't forget to put a second   #   to release the key "        
                toggleWindebug:=0
        } 
(closeloop) && text_out .= "`n}`n"
closeloop:=""

}

text_out:=removeemptylines(text_out)
guicontrol,, myedit2, %  text_out 

return
;--------------------------------------------------------------------------------------------------------

sk(key,KeyName) {
global
match_num:=""
regexmatch(substr(a_loopfield, k), "i)(^" key ")(?! *)?([0-9]+)",match_num)
        if (match_num) {
                match_num:=substr(match_num, 2)
                SendInput, {%KeyName% %match_num%}
        }
        else {
                SendInput, {%KeyName%}
        } 
} 

sk_debug(key,KeyName) {
global
match_num_deb:=""
regexmatch(substr(a_loopfield, k), "i)(^" key ")(?! *)?([0-9]+)",match_num_deb)
        if (match_num_deb) {
                match_num_deb:=substr(match_num_deb, 2)
                text_out .= "`nSendInput, {" KeyName "  " match_num_deb "}"
        }
        else {
                text_out .= "`nSendInput, {" KeyName "}"
        } 
} 

;---------------------------------------------------------------------------------------------------------


ButtonCLEAR:
clickscount:=0
myedit:=""
guicontrol,, myedit, % ""
return

ButtonLOAD:
Gui +OwnDialogs  ; Force the user to dismiss the FileSelectFile dialog before returning to the main window.
FileSelectFile, SelectedFileName, 3,, Open File, Text Documents (*.txt)
if SelectedFileName =  ; No file selected.
    return
Gosub FileRead
return

FileRead:  ; Caller has set the variable SelectedFileName for us.
FileRead, MyEdit, %SelectedFileName%  ; Read the file's contents into the variable.
if ErrorLevel
{
    MsgBox Could not open "%SelectedFileName%".
    return
}
GuiControl,, MyEdit, %MyEdit%  ; Put the text into the control.
return


ButtonSAVE:
Gui +OwnDialogs  ; Force the user to dismiss the FileSelectFile dialog before returning to the main window.
FileSelectFile, SelectedFileName, S16, %A_WorkingDir% , Save File, Text Documents (*.txt)
if SelectedFileName =  ; No file selected.
    return
CurrentFileName = %SelectedFileName%
Gosub SaveCurrentFile
return

SaveCurrentFile:  ; Caller has ensured that CurrentFileName is not blank.
IfExist %CurrentFileName%
{
    FileDelete %CurrentFileName%
    if ErrorLevel
    {
        MsgBox The attempt to overwrite "%CurrentFileName%" failed.
        return
    }
}
GuiControlGet, myedit  ; Retrieve the contents of the Edit control.
if ! instr(currentfilename, ".",,2)
FileAppend, %myedit%, %CurrentFileName%.txt  ; Save the contents to the file.
else
FileAppend, %myedit%, %CurrentFileName% ; Save the contents to the file.
return

commandlist:
list=
(
Add a line that begin with " : " to  insert a command in the Macro
Each letter represents a key command.
The standard AHK notation for keys is also supported. 
for ex. :{PgDn} u2 {Enter} = SendInput, {PgDn}{Up 2}{Enter}

$ (at the beginning of a command) = loop current command line `n    for ex. :$12 = loop 12 times :$5 = loop 5 times etc...
U D L R =  {Up} {Down} {Left} {Right}
S   =  Sleep, 1000
Sn =  Sleep, n seconds  (n=number or floating number)
         S3.2 = Sleep, 3200   S4 = Sleep, 4000 etc...
Bn  =  {BackSpace} (n = number of times the key is pressed)
for ex. B3 = SendInput, {Backspace 3) ; n is also compatible with commands E D H N T U D L R 
E  =  {Enter}
H  =  {Home}
N  =  {End}
T  =  {Tab}
K  =  {Appskey}
A  =  ^a  ; select all
X  =  ^x  ; cut
C  =  ^c  ; copy
V  =  ^v  ; paste
F  =  ^f  ; find
Q  =  {Alt}{F4}  ; Close
W  =  ClipWait
I  =  Increment the last number found in clipboard
       for ex. "dir05\file001.txt" to "dir05\file002.txt"
Z  =  Clipbaord clear
P  =  Plain text (convert clipboard to plain text)
M  =  Msgbox,
F1 to F24 = {F1} - {F24} ; function keys

()   = place text between parenteses to sendraw text
    for example
    :(Hello) + H + = Send, Hello {Shift Down}{Home}{Shift Up}

+  = {Shift Down/Up}  Toogle shift key  
     Don't forget to put a second + to release the key !!!
     for example
     :+ N + = Send, {Shift Down}{End}{Shift up}
     :++  = Send, {Shift Down}{Shift up}     (normal shift event)

^  = {Ctrl Down/Up}  Toogle Ctrl key  
     Don't forget to put a second ^ to release the key !!!
     for example
     :^ "o" ^ = Send, {Ctrl Down} o {Ctrl up}

!  = {Alt Down/Up}  Toogle Alt key  
     Don't forget to put a second ! to release the key !!!
     for example
     :! "fs" ! = Send, {Alt Down} fs {Alt up}
     
#  = {Win Down/Up}  Toogle Win key  
     Don't forget to put a second # to release the key !!!
     for example to open explorer
     : # "e" # = Send, {Win Down} e {Win up}  

other supported commands:

Run,  ; to run a program
RunOnce,  ; to run a program only once
SleepOnce, (millisec) ; to sleep only once (value in milliseconds)
WaitForColor, color, posx, posy, true/false   ; wait for a pixel color to become visible or invisible (false)
MouseClick, left/right, posx , posy
MsgBox, text ; display simple message box (options not supported)
   
)
return

removeemptylines(var){
loop, parse, var, `n, `r
	if !(a_loopfield=="") {
		out .= a_loopfield  "`n"
	}
return	out:=substr(out, 1, -1)
}

st_glue(array, delim="`n")
{
   for k,v in array
      new.=v delim
   return trim(new, delim)
}

getcontrol(crtname, what)
{
 guicontrolget, out,  Pos, %crtname%

 if (what="x")
 return % outx

 if (what="y")
 return % outy

 if (what="w")
 return % outW

 if (what="h")
 return % outH

 if (what="yh")
 return % outy + outH 

 if (what="xw")
 return % outx + outW
}



~#esc::
send, {shift up}
tooltip,
exitapp 
return

; =================================================================================
; Function: AutoXYWH
;   Move and resize control automatically when GUI resizes.
; Parameters:
;   DimSize - Can be one or more of x/y/w/h  optional followed by a fraction
;             add a '*' to DimSize to 'MoveDraw' the controls rather then just 'Move', this is recommended for Groupboxes
;   cList   - variadic list of ControlIDs
;             ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
;             The later (displayed text) is possible but not recommend since not very reliable 
; Examples:
;   AutoXYWH("xy", "Btn1", "Btn2")
;   AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
;   AutoXYWH("*w0.5 h 0.75", hGroupbox1, "GrbChoices")
; ---------------------------------------------------------------------------------
; Version: 2015-5-29 / Added 'reset' option (by tmplinshi)
;          2014-7-03 / toralf
;          2014-1-2  / tmplinshi
; requires AHK version : 1.1.13.01+
; =================================================================================
AutoXYWH(DimSize, cList*){       ; http://ahkscript.org/boards/viewtopic.php?t=1079
  static cInfo := {}
 
  If (DimSize = "reset")
    Return cInfo := {}
 
  For i, ctrl in cList {
    ctrlID := A_Gui ":" ctrl
    If ( cInfo[ctrlID].x = "" ){
        GuiControlGet, i, %A_Gui%:Pos, %ctrl%
        MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
        fx := fy := fw := fh := 0
        For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]")))
            If !RegExMatch(DimSize, "i)" dim "\s*\K[\d.-]+", f%dim%)
              f%dim% := 1
        cInfo[ctrlID] := { x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:a , m:MMD}
    }Else If ( cInfo[ctrlID].a.1) {
        dgx := dgw := A_GuiWidth  - cInfo[ctrlID].gw  , dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh
        For i, dim in cInfo[ctrlID]["a"]
            Options .= dim (dg%dim% * cInfo[ctrlID]["f" dim] + cInfo[ctrlID][dim]) A_Space
        GuiControl, % A_Gui ":" cInfo[ctrlID].m , % ctrl, % Options
} } }

Shortcuts:
Win + F12 = Hide Show Gui
Win + F11 = Play the macro
Win + Space = insert a left click.
Win + x = insert a right click.
Win + C = insert " wait for color "
Win + W = insert current window title as comment
Win + Esc = exit the script

Other supported commands:
Run, = to run a program
RunOnce, = to run a program only once
SleepOnce, (millisec) = to sleep only once (value in milliseconds)
WaitForColor, color, posx, posy, true/false = wait for a pixel color to become visible or invisible (false)
MouseClick, left/right, posx , posy = simple mouseclick (others options not supported)
MsgBox, text = simple message box (others options not supported)

Letters Dictionary:

Add a line that begin with " : " to insert a command in the Macro
or " :$ " to loop for ex. (:$7ud = send {up}{down} 7 times )
Each letter represents a key command.
Standard AHK notation for keys is also supported.
for ex. :{PgDn} u2 {Enter} = SendInput, {PgDn}{Up 2}{Enter}

S = Sleep, 1000
Sn = Where n represents number of seconds to sleep (floating number are supported)
for example S3.2 = Sleep, 3200 S4 = Sleep, 4000 etc...
B = {BackSpace}
Bn = n represents the number of times the key is pressed
for example B3 = SendInput, {Backspace 3) (also compatible with commands E D H N T U D L R)
U D L R = {Up} {Down} {Left} {Right}
E = {Enter}
H = {Home}
N = {End}
T = {Tab}
K = {Appskey}
A = ^a ; select all
X = ^x ; cut
C = ^c ; copy
V = ^v ; paste
F = ^f ; find
Q = !{F4} ; Close/Quit
W = ClipWait
I = Increment the last number found in clipboard (for ex. "dir05\file001.txt" to "dir05\file002.txt")
Z = Clipboard clear
P = Plain text (convert clipboard to plain text)
M = Msgbox,
F1 to F24 = {F1} - {F24} ; function keys

$n (dollar sign at the beginning of a command) = loop current command line (:$12 = loop 12 times etc...)
() = Place text between parentesis to send a text (sendraw)

toggle keys commands (first will be interpreted as down and second as up)
+ = {Shift Down/Up} Toogle shift key
^ = {Ctrl Down/Up} Toogle Ctrl key
! = {Alt Down/Up} Toogle Alt key
# = {Win Down/Up} Toogle Win key

examples:
:! (fs) ! f2= Send, {Alt Down} fs {Alt up}{F2}
:U2 R3 LS E = Send, {Up 2}{Right 3}{Left}{Sleep, 1000}{Enter}
:S2.5 (Hello World) = {sleep, 2500} Sendraw, Hello World
: ACNEV = Send, ^a ^c {End}{Enter} ^v

Practical examples:
duplicate the current line in a text editor

Code: Select all

:h +n+ c s0.2 n e v
open windows run command and send "charmap"

Code: Select all

:#(r)# s0.5 (charmap)
run notepad and say hello

Code: Select all

run, notepad
:s("hello world")
select all + copy + increment clipboard + past

Code: Select all

:aciv
run once notepad + sendraw 4 times "hello" and 2 times "world"

Code: Select all

runonce, notepad
sleeponce, 1000
:$4(hello)t
:$2(world)t
Regards
Last edited by SpeedMaster on 29 Dec 2019, 03:27, edited 25 times in total.
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.2

12 Feb 2019, 06:32

Pleasantly surprised by the efficiency of the concept (1 key = 1 command). :)
I decided to explore it a little more and made a new version with a new letters dictionary.
I also changed some shortcuts... :roll:

Regards
ahk7
Posts: 574
Joined: 06 Nov 2013, 16:35

Re: [Tool] Macro Commander v1.2

12 Feb 2019, 14:40

Entertaining :)

I recently added something to my clipboard tool, ccmder plugin:
https://github.com/hi5/CL3/blob/master/docs/ccmdr.md and https://github.com/hi5/CL3/blob/master/plugins/ccmdr.ahk
also one letter followed by number so instead of SS in your case I would have made it S2 or S5 for to sleep 2 or 5 times for example.

This makes a bit "vim" like. Before ccmder I toyed with a global VIM script (just testing around) but soon learned others have already done so and better. One example: https://github.com/rcmdnk/vim_ahk but there are various VIM ahk scripts floating around. Not that I use them but they are fun. Perhaps you can draw some inspiration from them :)
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.3

13 Feb 2019, 09:18

ahk7 wrote:
12 Feb 2019, 14:40
I recently added something to my clipboard tool, ccmder plugin:
Nice script, I suspected that something using same concept existed somewhere. ;)
The wheel is constantly being reinvented, but fortunately it is not always the same wheel... :D
ahk7 wrote:
12 Feb 2019, 14:40
also one letter followed by number so instead of SS in your case I would have made it S2 or S5 for to sleep 2 or 5 times for example.
Great suggestion. :idea: I added this feature in the new version (v1.3) at least for the Sleep command.
Now you can type S120 to sleep 120 sec floating numbers are also supported S 0.1 to sleep 100 ms...
I'll see later if I can do the same for the other command keys.

Cheers
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.5

15 Feb 2019, 10:22

New Version 1.5
  1. Added parameter n = number of times the key is pressed for ex. :T15 B3 etc...
  2. Activate focus on edit control
  3. Remplaced Send with SendRaw when sending as string for ex. :"Hello !"
Cheers,
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.6

16 Feb 2019, 17:56

New Version v1.6 ;)
  1. Standard AHK notation for keys is now supported.
    for ex. :{PgDn}U2R{Enter} = SendInput, {PgDn}{Up 2}{Right}{Enter}
  2. Added letter F folowed by a number to send a function key (F1 to F24)
    for ex. :U3F2 = SendInput, {Up 3}{F2}
  3. Added letter F (without number) for send, ^f ; find
  4. A key release command will be automatically added for the keys {shift} {control} {alt} {win} if they are still pressed at the end of a command line.
Cheers,
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.7

17 Feb 2019, 16:56

New Version v1.7 ;)
  1. Added repeat option (has to be used wisely and carefully :ugeek: )
  2. Fixed bug for sending digit zero (:"0") :thumbup:
Cheers,
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.7

21 Feb 2019, 05:22

v1.8 ? ? ? :o
Sorry, you have been blocked :cry:

It's working again. ;)
Thanks. :thumbup:
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.8

21 Feb 2019, 11:01

New Version v1.8 ;)
  1. Added the possibility to save and load a macro.
  2. Fixed bug case sensitive command parsing :thumbup:
  3. Added letter K for {Appskey} (the key that invokes the right-click context menu.)
  4. Added letter W for clipwait command
Cheers,
swub
Posts: 19
Joined: 25 Feb 2019, 09:16

Re: [Tool] Macro Commander v1.8

15 Aug 2019, 10:09

Thank you for this excellent tool. I do have a question how is the debug tab used?

Thank You,
swub
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.8

16 Aug 2019, 14:44

swub wrote:
15 Aug 2019, 10:09
I do have a question how is the debug tab used?
The debugger is used to see the transcription of a macro created in a standard AHK syntax.
It's handy to see if there's no error before running the macro. :roll:
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v1.8

04 Sep 2019, 15:34

New Version v2.0 ;)
  1. Added the function AutoXYWH() now the editing field can be resized.
  2. Small change in the layout (position of the buttons)
Cheers,
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v2.3

30 Sep 2019, 07:45

New Version v2.3 ;)
  1. Renamed tab Debugger to Transcriber
  2. Added button : Insert Mouse Delay between clicks (in the transcriber)
  3. Added button : Copy to clipboard (in the transcriber) so that it can be also pasted as a normal AHK script
Cheers,
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v2.4

18 Oct 2019, 16:20

New Version v2.4 ;)
  1. Added letter M for Msgbox (it is useful for interrupting the macro to perform tasks that cannot be automated or to debug the macro step by step)
Cheers,
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v2.5

01 Nov 2019, 06:30

New Version v2.5 ;)
  1. Added a checkbox to show the Gui again at end of the play.
  2. New letters:
    Z = Clipboard clear
    P = Plain text (convert clipboard to plain text)
Cheers
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v2.6

05 Nov 2019, 09:23

New Version v2.6 ;)
  1. Fixed some minor bugs.
  2. New letter:
    I = Increment the last number found in clipboard (useful for incrementing file numbers for ex. file001.txt to file002.txt etc...)
Cheers
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v2.8

24 Dec 2019, 04:17

New Version v2.8 8-)
  1. Modified the way to send a text : quotation marks are now replaced by parenthesis to send a string
    (place a text in parenthesis to sendraw it)
    :!: Note: this can cause incompatibility with previous saved macros but solve the problem for sending quoted text.
  2. Added WaitForColor command (shortcut #C)
    (the macro will wait for the selected colored pixel to appear on screen.)
  3. Added Run command (for ex. run, notepad.exe)
Cheer,
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: [Tool] Macro Commander v3.0

29 Dec 2019, 03:30

New Version v3.0 8-) :D
  1. Added possibility to loop specific macro command line
    add dollar sign at the beginning of a macro command line followed by the desired number of repetitions. (for ex. :$25)
  2. Added RunOnce command to run a program only once
  3. Added SleepOnce, (millisec) ; to sleep only once (value in milliseconds)
    Sleeponce and RunOnce state can be reseted with a button on gui
  4. Added True or False option for the WaitForColor command
    the macro will wait now for the selected colored pixel to appear (true) or disapear (false)
  5. Added possibility to insert AHK comment at the end of a macro command line (for ex. :ac ;select all and copy)
  6. Added possibility to insert basic message box lines MsgBox, (text) (other options are not supported)
  7. Fixed some bugs
Cheer,

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 162 guests