Showing posts with label AutoIT. Show all posts
Showing posts with label AutoIT. Show all posts

Friday, January 30, 2009

OpenDialog in Ruby

I have encountered some issues trying to get Ruby to open up an Open Dialog Box.
I tried doing it the DL route but apparently there is some problem with Ruby properly creating the struct to be passed to the 'GetOpenFileNameA' function (at least, that's what I've encountered). But I have found a different way...

Fortunately for me, I have delved into AutoIT scripting which allows me to create an Open Dialog Box. So I then decided to write a simple script to pass all the necessary params to this application from Ruby (i.e. Dialog message and filter) and the AutoIT application returns the filename that is selected or nil if canceled.

AutoIT code:

If $CmdLine[0] < 1 Then
ConsoleWriteError("No arguments given")
Exit
EndIf

$op = $CmdLine[1]

Switch($op)
Case "open"
If $CmdLine[0] < 3 Then
ConsoleWriteError("open command requires message and filter arguments.")
Exit
EndIf

$msg = $CmdLine[2]
$filter = $CmdLine[3]
$selected = FileOpenDialog($msg, "", $filter, 1)

If @error Then
ConsoleWriteError("Open Dialog problem")
Exit
EndIf

ConsoleWrite($selected)
EndSwitch


Ruby code:

f = IO.popen("controls.exe open \"Select a file\" \"Text File(*.txt)\"")

puts f.gets


This seems to work nicely. A bit of a round-trip but allows you to get what you need.
For those who don't know, AutoIT is a Windows-based automation scripting system (console and GUI wise, see some of my AutoIT posts).

Cheers!

Wednesday, April 30, 2008

AutoIT Script for EasyWorship

EasyWorship (EW) is a wonderful app for church services and beats Powerpoint in that it can display Powerpoint slides on a different monitor (than your primary for the projectors) and you can view all the slides in advance of what it beholds. This is great unless you want to import some old songs from a Word document or Powerpoint slides into its Song database...

Well why not just import the Powerpoint slides and use that? Well in my case (as I've been doing this at my church for over a year now) this can take a long time in preparation and is very error prone. What we usually did was create a Powerpoint slide and create our whole church service presentation in it, which meant opening up the Word or Powerpoint Doc with the original songs inside, search for it and then copy-paste. Sometimes we accidentally took the wrong songs (like Psalm 256 instead of 265) and found out in the Sunday morning service! :D
With the EW Song DB, you can type in the song title and you just drag it into your schedule. Thats it! Save me about ... hmm... 3-8 minutes per song!
Also this means that if we imported the wrong song and found out the Sunday morning, we can correct it in a matter of seconds!

We already have all our Psalms and Songs on Word Doc and Powerpoint and its not 1 song per doc, its a hundred at least! EW can only import 1 thing at a time and they haven't released a tool that can do convertions and imports for you like we needed so I searched the web to find out that everyone else who has the same problem as I did, import it manually! Man, I can't imagine importing over a 1000 songs manually by copy & paste! 8-0
So I stumbled on AutoIT. This is a wonderful util to automate just about any task. By writing a BASIC script (pun intended) you can tell the mouse pointer to move to a certain window's control and wait for a while and then issue a click action. Now that's what I mean by GUI automation ;-). You can also do basic scripting automation like a BATCH or BASH script can.

Now back to my scenario... I played around and found how easy it actually was to write a script that can import all my hundreds of songs in minutes (it literally took just over 20 mins to import over 800 songs!) since there wasn't a way for me to to it programatically in EW. This script is tested on EW 2006, so if you want to do the same kind of thing like I did, maybe your fortunate to have Google'd onto this page :D


#cs
A little script to import songs into Easy Worship 2006.
Written by Dandre Jansen van Vuuren
#ce

;Select the files to import
$var = FileProcessSelectionDialog()

;Cancelled
If $var == -1 Then
MsgBox(0, "Error", "No files selected, quitting...")
Exit (1)
EndIf

$selectedSourceFolder = False
$sourceFolder = $var[1]

StartEasyWorship()

;Iterate through all the selected files to import
$total = Number($var[0])

For $i = 2 To $total
$curFile = $var[$i]
SelectNewSong()
OpenFileOpenDialog()
$ext = MapFileTypeToTypeName(GetExtensionFromFile($curFile))
SelectAFileFromOpenDialog($curFile, $ext)
WinWaitActive("New Song")
Send("!o")
WinWaitActive("EasyWorship")
Next

MsgBox(0, "Progress", "Finished.")

Func FileProcessSelectionDialog()
$filter = "HTML Files (*.html;*.htm)|Word 97-2002 (*.doc)|Text Files (*.txt)"
$importFiles = FileOpenDialog("Select the files to import into EasyWorship", "", $filter, 1 + 4)

If @error Then
return -1
Else
If StringInStr($importFiles, "|") Then
return StringSplit($importFiles, "|")
Else
;A single selected file isn't in the same form as a multiple
;selection of files.
$pos = StringLastIndexOf($importFiles, "\")
$folder = StringLeft($importFiles, $pos)
$file = StringMid($importFiles, $pos + 1)
$newString = $folder & "|" & $file
return StringSplit($newString, "|")
EndIf
EndIf
EndFunc

Func StartEasyWorship()
Run("C:\Program Files\Softouch\EasyWorship\EasyWorship.exe")
WinWaitActive("EasyWorship")
EndFunc

Func SelectNewSong()
Send("!s")
Send("n")
WinWaitActive("New Song")
EndFunc

Func OpenFileOpenDialog()
;The open button doesn't have a shortcut
;find out where the window is positioned And
;relatively position the mouse onto the open button
$winPos = WinGetPos("New Song")
MouseMove($winPos[0] + 305, $winPos[1] + 45)
MouseClick("left")
WinWaitActive("Open")
EndFunc

Func SelectAFileFromOpenDialog($file, $type)
Send("!t")
ControlCommand("Open", "", "ComboBox3", "SelectString" , $type)
sleep(10)
Send("!n")
Sleep(10)

;We only need to specify the folder where all the files
;lie, once. From there on we can import the files one
;at a time.
If $selectedSourceFolder == False Then
Send($sourceFolder)
Send("{Enter}")
Sleep(10)
$selectedSourceFolder = True
EndIf

Send($file)
Send("!o")
EndFunc

Func GetExtensionFromFile($filename)
Return StringMid($filename, StringLastIndexOf($filename, ".") + 1)
EndFunc

Func StringLastIndexOf($string, $char_target)
$strlen = StringLen($string)
For $i = $strlen to 1 Step -1
$char = StringMid($string, $i, 1)
If $char == $char_target Then
return $i
EndIf
Next
EndFunc

Func MapFileTypeToTypeName($fileType)
Switch StringLower($fileType)
Case "html"
return "HTML Files"
Case "htm"
return "HTML Files"
Case "doc"
return "Word 97-2002"
Case "txt"
return "Recover Text from Any File"
Default
return "Unknown"
EndSwitch
EndFunc


Here is how the script works (you obviously need AutoIT and EW):

  • Run the script

  • Choose the files you would like to import, EW only has a limited supported file-base, but includes HTML and Word Docs. I reformatted all my songs to HTML (I'll write a new article on how I automated that process).

  • After selecting the files and clicking on Open, leave everything! You'll see your mouse pointer and menu-popping in action. :-)

  • Once it is done, it will pop up with a "Done" message box. In the mean time don't let anything take control of your keyboard, mouse, etc (including you ;-) ). This script doesn't cater for problematic scenarios!



I don't mean to be full of myself (really I don't!) but I am glad that God made me a programmer so that I wouldn't have to do these kind of tasks manually! :D