I hope, somebody out here can help me:
I have a windows application (only binary) which presents a window, where
some data strings have to be typed into input fields.
I need to do that for a lot of different tasks and want to automate this -
preferrably using Ruby, of course.
Unfortunately, i am mostly an Unix guy.
I have only little experience in Windows programming (but a lot in Unix).
Can anybody help me to make this happen in Ruby?
I will have to
1. Find the correct window (either by its title or ID - where to
get that from?)
2. Activate this window
3. Hope, that i am in the correct input field ;-)
4. Send key strokes to the input field
5. Send a tab in order to switch to the next field
6. Fill out all remaining fields
7. Activate an OK button.
I wrote some Ruby extension in C for Linux and have a working mingw
C-compiler environment, if C is neccessary here.
Although i would prefer doing this task with some kind of dl-interface or
something like that.
Thank you very much for any help in advance,
Martin.
You should be able to do this with DL. I probably can't help, but I'm going
to try, and make a fool of myself.
DL help is hard to come by:
http://www.ruby-doc.org/stdlib/libdoc/dl/rdoc/index.html
http://www.polarhome.com:793/manual/ruby-docs-1.6.8/refm-ja/refm0392.html
No, wait!
http://www.jbrowse.com/text/rdl_en.html
Thank you, Benjamin Peterson!
Microsoft's Windows API is available here:
http://msdn.microsoft.com/library/en-us/winprog/winprog/windows_api_reference.asp
> I will have to
> 1. Find the correct window (either by its title or ID - where to
> get that from?)
require 'dl'
user32 = DL.dlopen 'user32.dll'
# HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);
findWindow = user32['FindWindow', 'PPP'] # return Pointer, 2 Pointer params
window, args = *findWindow.call(nil, 'Window Title Goes Here!')
# <insert expletive here>, that worked! This is so much fun in irb.
> 2. Activate this window
# BOOL ShowWindow(HWND hWnd, int nCmdShow);
# Constants for nCmdShow:
SW_SHOWNORMAL = 1
SW_SHOWMAXIMIZED = 3
showWindow = user32['ShowWindow', 'IPI']
result, args = *showWindow.call(window, SW_SHOWNORMAL)
# Doesn't work that great... next function:
# BOOL SetForegroundWindow(HWND hWnd);
setForegroundWindow = user32['SetForegroundWindow', 'IP']
result, args = *setForegroundWindow.call(window)
# Much better... you'll need to use both show and foreground, I think
> 3. Hope, that i am in the correct input field ;-)
I think this feature got dropped from Longhorn...
No, seriously, you do need to drill down to an input field.
# HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,
# LPCTSTR lpszClass, LPCTSTR lpszWindow);
findWindowEx = user32['FindWindowEx', 'PPPPP']
#control = findWindowEx.call(window, nil, 'ControlTypeGoesHere', nil) # ???
# I'm out of time on figuring out how to use this, sorry. Reference here:
http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/findwindowex.asp
> 4. Send key strokes to the input field
# BOOL PostMessage(HWND hWnd,UINT Msg,
# WPARAM wParam, LPARAM lParam);
# Msg constants:
WM_KEYDOWN = 0x0100
WM_KEYUP = 0x0101
WM_CHAR = 0x0102
postMessage = user32['PostMessage', 'IPIII']
#postMessage.call(window, WM_KEYDOWN, ?X, ?X << 16) # ???
#postMessage.call(window, WM_KEYUP, ?X, 0) # ???
# again, out of time on making this work
> 5. Send a tab in order to switch to the next field
> 6. Fill out all remaining fields
> 7. Activate an OK button.
# Step 1: FindWindowEx or something to get the button
# Constant for PostMessage:
BM_CLICK = 0x00F5
postMessage.call(button, BM_CLICK, 0, 0)
> I wrote some Ruby extension in C for Linux and have a working mingw
> C-compiler environment, if C is neccessary here.
> Although i would prefer doing this task with some kind of dl-interface or
> something like that.
That was DL. I don't think you'll find any limitations with this basic stuff
that would make it easier to drop down to C/C++.
>
> Thank you very much for any help in advance,
> Martin.
That was kinda fun and maybe even educational. Thanks for the question,
Martin. Good luck.
Cheers,
Dave
Paul
"Dave Burt" <da...@burt.id.au> wrote in message news:<YBFVd.182663$K7.2...@news-server.bigpond.net.au>...
Take a look at:
http://www.rubygarden.org/ruby?AutoIt_For_Windows
The AutoIt package (link near top of page) can be run
from Ruby via WIN32OLE.
I think that's the easiest way.
Maybe Dave Burt could confirm ? (Epic reply, BTW :-)
daz
I haven't tried it, but it looks like it'll do the job. You'd have to
install the COM component, but it'll make your job easier.
Alternately, there is Paul's suggestion of win32/guitest.
And if you don't mind dropping down to Perl, there's Win32::GuiTest on that
platform :)
http://search.cpan.org/author/CTRONDLP/Win32-GuiTest-1.50.3-ad/guitest.pm
(Are you allowed to post CPAN links in this newsgroup? *ducks*)
Cheers,
Dave
Thank you very much for all of the replies!
I will have a look - especially on guitest (even the perl version).
Let's see if that does the job.
Thanks again,
Martin.
You're welcome :)
> I will have a look - especially on guitest (even the perl version).
>
> Let's see if that does the job.
Note that ruby's win32/guitest (linked in Paul's message) requires cygwin.
And I didn't get it working even with cygwin... although it may just be a
DLL path issue.
Cheers,
Dave