Sign in to follow this  
Followers 0
a1l0s2k9

GUI to manage your scripts

5 posts in this topic

In the past I've used a commercial tool named Macro Scheduler. I've now completely converted to the great tool that is AutoIt!

Overall AI is much better than MS, but if you create a lot of macros for day to day work the fact that AutoIt doesn't have a GUI that allows you to easily/centrally keep track of scripts and bind hotkeys is kind of annoying.

MS has a rather simple GUI that allows one to execute a script, edit a script, assign a hotkey, and a couple other things. I've re-created the parts of MS's GUI that are most important to me using AI's native functionality.

I'm very new to AI, so I hope I'm not re-inventing the wheel... I didn't see any similar projects. Also, because I'm new it's very likely my script is much worse than it has to be. Any feedback on how to make it better would be greatly appreciated.

Lastly, to achieve my primary goal, I had to do some hackery, and I'm hoping someone can suggest cleaner methods. My primary goal was to be able to assign/manage a hotkey to a script, without embedding information about the hotkey into the script I'm assigning it to. For example, if I want to assign CTRL-N to a script named "FOOBAR.AU3", I don't want "FOOBAR.AU3" to have any knowledge of the CTRL-N sequence -- I wanted this entirely managed by the GUI/management tool.

I tried several ways to achieve this, such as:

TRY #1

for $i = 0 to $number_of_scripts

hotkeyset($key, "runMacro($macro[$i]")

next

TRY #2

for $i = 0 to $number_of_scripts

func $macro[$i] ()

runMacro($macro[$i])

endfunc

next

TRY #3

for $i = 0 to $number_of_scripts

$fh = FileOpen($macrofile, 2)

FileWriteLine($fh, "func " & $macro[$i] & "()" & @CRLF & "runMacro('" & $macro[$i] & "')" & @CRLF & "endfunc")

FileClose($fh)

next

#include $macrofile

; I also tried including the file via an absolute reference.

As you can see, I ran into several limitations:

1) You can't pass function parameters when assigning hotkeys

2) You can't create dynamically-named functions (you also can't have embeded functions, either)

3) You can't #include variable-named files

4) You can't #include anything at run-time with the normal execution of the script (it seems to be done via pre-processor)

In the end, I made a terrible hack to workaround these limitations. I created several scripts:

1) "main" script that does all the work, has the GUI, ...

2) multi-stage startup script that executes "main"

3) seperate dynamically-generated include file that contains functions which call my runMacro() function. One function per macro/hotkey is generated.

Initially the multi-stage startup script executes "main" with a parameter indicating that it should only attempt to generate the include file, then exit. Then the multi-stage startup script executes "main" again, this time with a parameter that indicates "main" should run normally, and #include the file that was dynamically generated on the first run.

This is very un-clean. Worst of all, I have to restart the GUI every time key binding changes are made.

Is there a better way? I hope so!

Thanks!

a1l0s2k9

The program is not entirely finished, so getting it working requires a little work:

1) Install AutoItV3 using the latest stable/release as of today, accept all default settings

2) Install SciTE using the latest stable/release as of today, accept all default settings

3) Create a directory named c:\progra~1\autoit3\aimanager

4) Name each of the files as described below using the contents provided, and place them in the above-mentioned directory.

Now execute "aimanager.au3" and it should be self-explanatory.

------------- CUT HERE, restart_aimanager.au3 START -------------

#include "aimanagerglobals.au3"

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

; This script exists so the main program (aimanager) can be run twice, each time

; with different arguments. This is necessary because for the main program to run

; properly it must include a dynamically-generated include file. Because AutoIt doesn't

; actually support dynamic include files (they can ONLY be hard-coded), it's necessary

; to first create the dynamic include file (stage1), and then completely restart the

; program to re-include the file with the new dynamically-generated settings.

;

; If the main program is run without any arguments, it will launch this script and exit itself

; so as to ensure the program always goes through this 2-stage startup sequence. Unfortunately

; this means if you start the main program directly, it actually gets started 3 times before it

; can run normally.

;

; This script is also re-run any time the main program makes any keybinding changes to a

; script including adding/deleting a script. The main program calls this script and then

; exis itself.

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

; stage 1 creates a #include file that is needed to initialize hotkeys

; must wait for this to complete before proceeding

runMacroWait("aimanager", 1)

; once stage 1 is complete, load the main program normally, and exit this script

runMacro("aimanager", 2)

Exit

------------- CUT HERE, restart_aimanager.au3 END -------------

------------- CUT HERE, macros.au3 START -------------

func test()

runMacro('test')

endfunc

------------- CUT HERE, macros.au3 END -------------

------------- CUT HERE, aimanagerglobals.au3 START -------------

#NoTrayIcon

Global $scite_title = "SciTE"

Global $default_dir = "c:\progra~1\autoit3\aimanager"

Global $inifile = "aimanager.ini"

Global $macrofile = "macros.au3"

Func editMacro($macro, $parm = 0)

if $parm = 0 then $parm = ""

Run(@ComSpec & ' /c start scite "' & $default_dir & '\' & $macro & '.au3" ' & $parm, "", @SW_HIDE)

WinWaitActive($scite_title, "", 5)

EndFunc ;==>editMacro

Func runMacroWait($macro, $parm = 0)

if $parm = 0 then $parm = ""

RunWait(@ComSpec & ' /c start "" "' & $default_dir & '\' & $macro & '.au3" ' & $parm, "", @SW_HIDE)

EndFunc ;==>runMacro

Func runMacro($macro, $parm = 0)

if $parm = 0 then $parm = ""

Run(@ComSpec & ' /c start "" "' & $default_dir & '\' & $macro & '.au3" ' & $parm, "", @SW_HIDE)

EndFunc ;==>runMacro

------------- CUT HERE, aimanagerglobals.au3 END -------------

------------- CUT HERE, aimanager.ini START -------------

[macros]

test=^n

------------- CUT HERE, aimanager.ini END -------------

------------- CUT HERE, test.au3 START -------------

msgbox(0,"title","text")

------------- CUT HERE, test.au3 END -------------

------------- CUT HERE, aimanager.au3 START -------------

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

; INITIALIZE GUI

#include <GuiConstants.au3>

GUICreate("AutoIt Menu", 290, 275, (@DesktopWidth - 300) / 2, (@DesktopHeight - 300) / 2, $WS_OVERLAPPEDWINDOW + $WS_CLIPSIBLINGS - $WS_MAXIMIZEBOX)

$Group_1 = GUICtrlCreateGroup("Macros", 10, 10, 200, 220)

$List_macros = GUICtrlCreateList("", 20, 30, 130, 200, $WS_BORDER + $WS_VSCROLL + $LBS_NOTIFY)

$List_keys = GUICtrlCreateList("", 150, 30, 50, 200, $WS_BORDER + $WS_VSCROLL + $LBS_NOTIFY + $LBS_NOSEL)

$Button_run = GUICtrlCreateButton("&Run", 220, 25, 60, 30)

$Button_edit = GUICtrlCreateButton("&Edit", 220, 60, 60, 30)

$Button_set = GUICtrlCreateButton("&Set Key", 220, 95, 60, 30)

$Button_del = GUICtrlCreateButton("&Delete", 220, 130, 60, 30)

$Button_new = GUICtrlCreateButton("&New", 220, 165, 60, 30)

$Button_quit = GUICtrlCreateButton("&Quit", 220, 200, 60, 30)

$Button_rst = GUICtrlCreateButton("R&estart", 20, 240, 60, 30)

$Button_hide = GUICtrlCreateButton("&Hide", 100, 240, 60, 30)

; /GUI

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

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

; INITIALIZE MAIN GLOBALS

#include <Array.au3>

#include "aimanagerglobals.au3"

#include "c:\progra~1\autoit3\aimanager\macros.au3"

opt("WinTitleMatchMode", 2)

Global $list_macros_arr[100]

Global $list_keys_arr[100]

Global $hidden = 0

HotKeySet("^\", "unhide")

; /MAIN GLOBALS

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

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

; INITIALIZE FUNCTIONS

Func restart_self($param = 0)

if $param = 0 Then

if MsgBox(4, "Restart", "Must restart for changes to take effect, restart now?") <> 6 Then

Return

EndIf

EndIf

$macro = "restart_aimanager"

runMacro ($macro)

Exit

EndFunc ;==>restart_self

If $CmdLine[0] = 0 Then

restart_self(1)

EndIf

Func InitScriptDir()

If FileChangeDir($default_dir) Then

; chrdir worked fine, do nothing

Else

; try creating dir

If DirCreate($default_dir) Then

; create worked, try to chdir

If FileChangeDir($default_dir) Then

MsgBox(0, "NOTICE", "Created script directory: " & $default_dir)

Else

MsgBox(0, "ERROR", "Created script directory, but failed to change into it: " & $default_dir)

EndIf

Else

MsgBox(0, "ERROR", "Failed to create script directory: " & $default_dir)

Exit

EndIf

EndIf

EndFunc ;==>InitScriptDir

Func initScripts()

$fh = FileOpen($macrofile, 2)

If $fh = -1 Then

MsgBox(0, "ERROR", "Failed to open macro file: " & $macrofile)

Exit

EndIf

$macro_arr = IniReadSection($inifile, "macros")

If @error Then

MsgBox(0, "ERROR", "Reading INI file failed")

Exit

EndIf

For $i = 1 To $macro_arr[0][0]

$macro = $macro_arr[$i][0]

FileWriteLine($fh, "func " & $macro & "()" & @CRLF & "runMacro('" & $macro & "')" & @CRLF & "endfunc")

Next

FileClose($fh)

If $CmdLine[1] = 1 Then

Exit

EndIf

For $i = 1 To $macro_arr[0][0]

$macro = $macro_arr[$i][0]

$key = $macro_arr[$i][1]

GUICtrlSetData($List_macros, $macro)

GUICtrlSetData($List_keys, $key)

_ArrayInsert($list_macros_arr, $list_macros_arr[0]+1, $macro)

_ArrayInsert($list_keys_arr, $list_macros_arr[0]+1, $key)

$list_macros_arr[0] = $list_macros_arr[0] + 1

HotKeySet($key, $macro)

Next

EndFunc ;==>initScripts

func delMacro($macro)

if MsgBox(4, "Delete", "Are you sure you want to delete: " & $macro & "?") <> 6 Then

Return

EndIf

FileDelete($default_dir & '\' & $macro & '.au3')

$key = IniRead($inifile, "macros", $macro, "ERROR")

IniDelete($inifile, "macros", $macro)

HotKeySet($key)

for $i = 1 to $list_macros_arr[0]

if $list_macros_arr[$i] = $macro Then

_ArrayDelete($list_macros_arr, $i)

_ArrayDelete($list_keys_arr, $i)

$list_macros_arr[0] = $list_macros_arr[0] - 1

ExitLoop

EndIf

Next

GUICtrlSetData($List_macros, "|")

GUICtrlSetData($List_keys, "|")

for $i = 1 to $list_macros_arr[0]

GUICtrlSetData($List_macros, $list_macros_arr[$i])

GUICtrlSetData($List_keys, $list_keys_arr[$i])

Next

EndFunc

func hide()

traytip("How to unhide", "Hold CTRL and press BACKSLASH (^\, CTRL-\) to unhide", 5, 1)

$hidden = 1

GUISetState(@SW_HIDE)

EndFunc

func unhide()

if $hidden = 1 Then

$hidden = 0

GUISetState(@SW_SHOW)

WinActivate("AutoIt Menu")

Else

hide()

EndIf

EndFunc

; /FUNCTIONS

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

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

; RUN INITILIZATION

InitScriptDir()

initScripts()

; /INIT

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

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

; MAIN

Opt("TrayIconHide", 0)

GUISetState()

While 1

$msg = GUIGetMsg()

Select

Case $msg = $GUI_EVENT_CLOSE

if MsgBox(4, "Quit", "Are you sure you want to quit?") <> 6 Then ContinueLoop

ExitLoop

Case $msg = $GUI_EVENT_MINIMIZE

hide()

Case $msg = $Button_run

$list_selected = GUICtrlRead($List_macros)

if $list_selected = "" Then ContinueLoop

runMacro ($list_selected)

Case $msg = $Button_edit

$list_selected = GUICtrlRead($List_macros)

if $list_selected = "" Then ContinueLoop

editMacro ($list_selected)

Case $msg = $Button_set

$list_selected = GUICtrlRead($List_macros)

if $list_selected = "" Then ContinueLoop

$current_key = IniRead($inifile, "macros", $list_selected, "ERROR")

if $current_key == "ERROR" Then

MsgBox(0, "ERROR", "INI file in inconsistent state, no keybinding found for: " & $list_selected)

Exit

EndIf

$key = InputBox("Change keybinding", "Key shortcut: ", $current_key)

if @error = 1 OR $key = "" OR $current_key = $key Then ContinueLoop

IniWrite($inifile, "macros", $list_selected, $key)

restart_self()

Case $msg = $Button_del

$list_selected = GUICtrlRead($List_macros)

if $list_selected = "" Then ContinueLoop

delMacro($list_selected)

Case $msg = $Button_new

$list_selected = InputBox("New AutoIt Script", "Name: ", "new")

if @error = 1 OR $list_selected = "" Then ContinueLoop

$key = InputBox("New AutoIt Script", "Key shortcut: ", "^n")

if @error = 1 OR $key = "" Then ContinueLoop

IniWrite($inifile, "macros", $list_selected, $key)

editMacro ($list_selected)

restart_self()

Case $msg = $Button_quit

if MsgBox(4, "Quit", "Are you sure you want to quit?") <> 6 Then ContinueLoop

ExitLoop

Case $msg = $Button_rst

if MsgBox(4, "Restart", "Are you sure you want to restart?") <> 6 Then ContinueLoop

restart_self(1)

Case $msg = $Button_hide

hide()

Case Else

;;;

EndSelect

WEnd

Exit

; /MAIN

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

------------- CUT HERE, aimanager.au3 END -------------

Share this post


Link to post
Share on other sites



Hi

Seems a good work, but I would like it to be either downloadable or formatted with

["CODE"]

Your Code

["/CODE"]

(without quotes)

peethebee


vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvGerman Forums: http://www.autoit.deGerman Help File: http://autoit.de/hilfe vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

Share this post


Link to post
Share on other sites

this is a really cool script! if you don't mind, theres a quick change i might want to make so that the user doesnt have to edit the file to change $default_dir. I'll PM the results to you


The cake is a lie.www.theguy0000.com is currentlyUP images.theguy0000.com is currentlyUP all other *.theguy0000.com sites are DOWN

Share this post


Link to post
Share on other sites

Just skimming at the moment, but I noticed you were having trouble with passing parameters to hotkeyed functions. There is a macro available to hotkey functions that tells it what key combination was pressed. Using this, you should be able to rig it up to do what you want.

HotKeySet('^a', '_HotKeyFunc')
HotKeySet('^b', '_HotKeyFunc')
HotKeySet('^c', '_HotKeyFunc')

Func _HotKeyFunc()
  Switch @HotkeyPressed
    Case '^a'
      MsgBox(0, 'Key', 'You pressed Ctrl+A')
    Case '^b'
      MsgBox(0, 'Key', 'You pressed Ctrl+B')
    Case '^c'
      MsgBox(0, 'Key', 'You pressed Ctrl+C')
  EndSwitch
EndFunc

Share this post


Link to post
Share on other sites

Just skimming at the moment, but I noticed you were having trouble with passing parameters to hotkeyed functions. There is a macro available to hotkey functions that tells it what key combination was pressed. Using this, you should be able to rig it up to do what you want.

I was looking for this, I don't know how I missed it in the documentation (thanks!). Unfortunately it still doesn't allow me to change/add key bindings without restarting the script. I haven't figured out any magic just yet.

As you (and others) noticed the script is still just a prototype of my end goal. Once I've cleaned it up a bit I'll probably re-post (with the appropriate CODE /CODE tags). Hopefully by then I'll have figured out a way to add/change key bindings without a restart.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0