Showing posts with label windows. Show all posts
Showing posts with label windows. 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!

Thursday, May 01, 2008

Ruby and Win32 API

If you are using Ruby as an automation process rather than a development tool, you sometimes might want to use some of Windows' GUI controls, such as a message box or folder browser box. In those cases, you might want to try the DL library.

Some of you have read this post about OLE Automation and DL. In a way it is quite simple but it can take a while to get right, especially if you're a beginner like me. However, after some time I have managed to get my folder browser to work and I haven't found Ruby code on the web that does this yet.
However, I feel like it is rather simple to do and to find out how to make your own version, all you need to do is to see how people who wrote VB code do it.
Why? Because it is that straight forward, in fact, Ruby reduces the amount of lines of code to do it.

I must warn and say that doing this kind of programming requires excessive use of the Win32API docs (one form or another) and some skilled programming, especially in the C-language area, because you are interfacing to the actual C-functions from Ruby.

Many VB code snippets that does this, have referenced these 2 c-functions (from the shell32 DLL):
  • SHGetPathFromIDListA

  • SHBrowseForFolderA

They also require a structure to send data to the BrowseForFolder function.
Here is a site to get you started.

Why don't I just paste the code? Well, actually the method I wrote to bring up the dialog box, requires a whole Module and I would like to write my own Ruby module before I publish anything.
Yeah, I might sound like a bugger but hey, I have posted lots of lines of code on this site before so... take it like a man! ;)
The hardest part is creating a Ruby C-like structure from the VB structure, so I think I'll help you out on that one:

ptr = DL.malloc(DL.sizeof('LLSSLLLL'))
ptr.struct!('LLSSLLLL', :br_hOwner, :br_pidRoot, :br_displayName, :br_title,
:br_flags, :br_fn, :br_lparam, :br_iImage)

Now don't say I didn't give you anything! :D

For those who still don't know what all those L's and S's are for, it is basically saying "This is a Long integer type" or "This is a string type". Its to determine the size of the structure, but you know that there are other data-types so you need to dig in on your own regarding that.

Now there is one thing I'm having trouble with and it is the Open/Save File Dialog box. Aparently if you take the exact same data-types as the prescribed docs say, Ruby fails to bring it up. After hours of struggling, I decided to skip the VB code and look on the web if someone already did this, and to my "surprise", nobody has posted any code on this. Bummer! So I decided to have a look on the MSDN site, and BAM! I found my answer. The reason why Ruby didn't bring up my dialog box was due to the fact that Ruby created a structure that had a different size than what the function was expecting! So now I am trying to find out where, how and why.

I might post my code and findings at a later stage, for this is a necessary thing for Windows Ruby Automation Programmers, like me! ;)

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

Tuesday, April 15, 2008

Windows Explorer alternative

For those who're tired of Windows Explorer, a very nice free alternative I found does what I want it to and more...

There are a wide variety of Explorer replacements (or alternatives) that are "better" than Windows Explorer but this one I believe beats all of them in a lot of categories.
Ever heard of UltraExplorer?
Its a Delphi project (free for windows) and most people believe that Delphi GUI apps perform faster (and there is no exception in this case), although sometimes it might just stall for a while but I think it might be more of an IO stall than a "I'm too busy to listen to you" stall. ;-)
Its got a nice appearance, with skinable components (menu and toolbar). It has views that are actually customizable and very useful (except its console, that needs some work but you can get a very nice console app from Sourceforge as alternative to Windows').
You have tabbed windows support that works just life Firefox's tabs (even with the middle click event). It remembers where it was and has all the Windows Explorer context menus, and so on.
It even picks up my USB drives instantly as soon as Windows activates them and is very responsive except maybe during heavy disk IO.
I am definitely sticking to this handy tool for Windows, I even removed 'My Computer' and 'My Documents' from my desktop to replace it with 'Ultra Explorer'.

Hope you might like it. :)

God Bless.

Monday, March 31, 2008

Ruby, ruby, ruby ...

Yeah it's been a while since the last posting. I was lacking some inspiration on what to blog on or I was just too lazy or too busy to actually log in and blog on something that I wanted to, that is until now...

You might ask, whats up with the title? Well I remember the song written by a band called Keizer Chiefs (spelling) named: Ruby. Now that reminds me of the Ruby scripting language which lots of people on the web is going on about. A dynamic typed language with multiple ways of saying one thing.

I was among those who agreed that Ruby was stupid, until I wanted to do a few things in Windows which Python nor other scripting languages could offer (or easily accomplish), except Ruby. Some of us would mock the guy who presented a brief crash course in Ruby, saying that it is too dynamic for our taste and it would make debugging a nightmare, etc. but doing some code delving and with the latest Netbeans language addition, which is Ruby and Ruby on Rails of course, I started to see how cool Ruby actually is.
Usually I despised dynamic typed languages until I saw how it can increase productivity and coding speed for smallish scripts, which is what I wanted for automation.

"What kind of automation?" you may ask. Well ordinary and OLE automation. Sure AutoIT is great for GUI and other windows automation but the scripting language is very BASIC (pun intended) lacking structure and (as in, I need structures as in C or C++'s structures or atleast...) object orientation. With Ruby we have good OO support and with the 'win32ole' lib, you can kick VBA and do MS Office automation via Ruby instead. A good starting site is Ruby on Windows which covers Ruby automation in MS Office. I managed to convert Powerpoint slides to somewhat formatted Word docs via Ruby, just to give you an idea.

I think I'll post a couple of script snippets later on, on what I worked on with Ruby and AutoIT for others to see and for future reference.

Just to go back to Python, some of you might say that Python does have OLE automation... I had a look at it and it looked very nasty! I wouldn't touch it, unless I looked at the wrong files, and you need to download a library for Python to have OLE automation ability. With Ruby you use the OLE objects exactly as in VBA but within your Ruby context.

Currently I am trying to implement a few operations in Ruby to have Browse-For-Folder ability, Open-Dialog, and so on functionality by doing Windows API calls via the DL lib in Ruby. You can catch a quick course on DL here.

I hope this will help you as much as it helped me.
God Bless!

Tuesday, January 02, 2007

Bad Vista!

You're probably saying: "Oh no, not you too, an Anti-Vista fanatic!" and you might be right!
I want to share this new OS not to discredit MS but their newly released Vista. I like Windows XP, I am using it for years and think it's the best OS that MS has released in years but Vista is for me a huge disappointment and a waste of money (especially for us South-Africans)!

I'll extend my list of reasons after this list provided by an other Linux Blogger:

25 Shortcomings of Microsoft Vista OS

I would like to add:
  • That OpenGL is also being compromised by calling Direct3D functions instead of having its own traditional OpenGL library handling 3D graphics. Don't you think it will affect performance?
  • All the new games coming out will use Shader Model 4.0 (fully or partially) which is only found in DirectX 10.0 and that is only for Windows Vista.
  • You need a strong computer and graphics hardware to run Vista ordinarily, never mind the heavy games. Also you need to spend so much on Vista, your new computer, and your new games that you'll be in the red if you're not a rich dude! Like you need a "Vista Ready" machine.

FSF starts campaign to enlighten computer users against Microsoft's Vista OS

Vista restricts the user immensely, so read that before going "YEAH VISTA!!!"

I've been feeling bad about Vista for a long time and so far it hasn't improved to change my mind. I even worked with Vista - Beta on a machine at university, it was slow, stalled a lot, chowed a lot of RAM and that wasn't even the 3D option (and its one of those new DELL machines with 512 MB DDRII RAM, Intel 2.8 GHz HT CPUs, etc)!

So far all I saw, read and heard about Vista was negative stuff, I didn't even see 1 positive thing myself. Can someone please tell me what is so great about Vista that MS wants to force us all to use that OS instead of older or alternative OSs? Please, I really want to know! (for curiosity sake)
I really hope that other vendors (for programming, etc.) won't create their SDKs and Development software to be Vista-only in the future!

Thursday, November 02, 2006

Installing Linux from Windows

Who would have ever thought! Installing Linux from Windows! Yeah I stumbled across this article and found it pretty interresting to mention here for those who are interrested.
You can either read the long document or load instlux to install Linux from Windows. The author did mention that it would be a very good idea to backup everything!
I myself haven't tried this but if I am in the mood and I have some time available, I think I'll give it a go! Unless some of you would or have. In that case please tell me how it is. Is it easier, better, ... ?

Article: http://marc.herbert.free.fr/linux/win2linstall.html
Instlux: http://sourceforge.net/projects/instlux

Well see yah everyone!