March 19, 2003
Driving win32 GUIs with Python, part 1

I'm doing a lot of this at the moment, so I thought I'd jot down some of the stuff I've learnt. Certainly, I couldn't find any of this on the 'net at the moment.

I'm not going to post everything at once - I'll do it a piece at a time.

OK, so you are trying to automate some process, and one of the applications involved doesn't want to play. No COM automation, no command line, no nothing. You are going to have to drive its GUI.

One possibility (the first that I tried) is to use something like AutoIT. This (free) automation tool can drive a lot of things, and a COM control is provided, so you can script it all in Python. Problem is, if you push it too hard, the rough edges start to show. I find I need to reset the control (using the Init() method) all the time, or it would stop recognising windows. One of the applications I'm working with doesn't play by the Windows rules, and so not everything works. Lastly, it's inherently limited - you cannot, for example, use it to get the text from an edit control. For all these reasons, I frequently have to roll my own.

To run this lot, you'll need Python, and Mark Hammond's win32 stuff. I'm using version 2.2.2 and build 152 respectively, on NT 4 service pack 6. If any of this works (or doesn't) on other versions, I'd be grateful to know.

First step - before you can do anything with a GUI component, you'll have to find it. Bit of terminology or you - every Windows GUI component is a window, whatever it is; text area, application window, scroll bar, button, whatever, they are all windows. And each of them has a window handle (often called hwnd). Windows often live in other windows, and can contain yet more windows themselves, so we will end up getting all nasty and recursive. We'll start out by getting a list of the top level windows.

First, we'll import some stuff. We'll need all these modules eventually,

import win32api
import win32con
import win32gui

We are going to use the win32gui.EnumWindows() function to get our top level window information. This is one of those nasty functions which wants a callback function passed to it (consult the docs if you are really bored). So here's one I made earlier:

def windowEnumerationHandler(hwnd, resultList):
'''Pass to win32gui.EnumWindows() to generate list of window handle, window text tuples.'''
resultList.append((hwnd, win32gui.GetWindowText(hwnd)))

We can pass this, along a list to hold the results, into win32gui.EnumWindows(), as so:

topWindows = []
win32gui.EnumWindows(windowEnumerationHandler, topWindows)

Our topWindows list now contains an entry for each of the top level windows, probably quite a lot of them. Go on print it out. Each entry has the windows handle, and the window text, which we'll use to decide which top level window we are going to dig into. Once we have this, we'll use win32gui.EnumChildWindows() to burrow down to find whichever control we want to do something with.

But that's enough for one day...

Update: See the whole series: Driving win32 GUIs with Python, part 1, Driving win32 GUIs with Python, part 2, Driving win32 GUIs with Python, part 3, Driving win32 GUIs with Python, part 4 and 7 hours, one line of code.

Posted to Python by Simon Brunning at March 19, 2003 01:50 PM
Comments

Interesting introduction to Win32 programming from Python. I look forward to future articles. Perhaps you should consider collecting and publishing these outside of your weblog once you are done.

Posted by: Anthony Eden on March 19, 2003 02:32 PM

One of the sick and twisted things about this is that we've been using the book "Dan Appleman's Guide to the Win32 API for VB"... which is a Bible by a Guru for many VB people. Just thought I'd mention it as using a term like "VB" near Simon usually produces convulsions ;-)

Posted by: Mark Matthews on March 19, 2003 03:06 PM

*nods head in agreement*

Posted by: Eloon on March 19, 2003 04:39 PM

I recently embarked on this exact same quest. If you run into my problem [1] but can actually find a solution, I'd love to hear about it! :-)

[1]
http://www.injektilo.org/archives/2003/03/03/win32_automation_woes.html

Posted by: Jason on March 20, 2003 12:46 AM

Hi, If you are into win32 programming using ctypes,
check out the source distro of ctypes,
deep in the sample folder is a little package I wrote called wtl, it is a small toolkit style python library to create highly native win32 GUI programs. (Just a collection of small wrappers for MSG cracking, window creation etc).
Check it out!

Posted by: Henk on April 24, 2003 01:43 PM

I want to know how to use tabbed panel in win32 programming. I need an example program for that.
Thanks in advance

Posted by: vidya b on May 19, 2003 05:18 AM

Simon, I would like to thank you for your contribution of winGuiAuto. This python module has helped solve some of my own automated testing problems.

My project:
http://www.ishpeck.net/?P=b1115225809ishpeck


Thanks!
~ Ishpeck

Posted by: Ishpeck on May 4, 2005 07:14 PM

I've been having some good sucess with Autoit. I'm trying to figure out how it's limited.

I have noticed that I can't do some things in Autoit like select menus, or click on some controls. Are you saying I could do those things with the Python method?

Posted by: Greg on December 2, 2005 06:21 PM

Yes, exactly that. But it's hard work...

Posted by: Simon Brunning on December 2, 2005 08:46 PM

So you're saying there's no easy answer? It would still be hard work even if I use your library?

>>Yes, exactly that. But it's hard work...

By the way, what's the programmer's ethos in gui automation? Should it really be a last resort? How hard should we work to make another program "play nice" with Python first?

-Greg

Posted by: Greg on December 7, 2005 07:37 PM

This all looks very interesting, but what I really need is something to drive Firefox. Any idea whether winGuiAuto can do that, or should I be thinking about writing a Firefox extension?

Posted by: gudonov on January 18, 2008 09:28 PM

computer classes in zip 90278 funny car drag video breast implants gone wrong nostalgia merchanvhs movies

Posted by: Dimka on October 27, 2008 08:45 AM

Posted by: Alina_m on October 31, 2008 11:16 PM
Post a comment
Name:


Email Address:


URL:



Comments:


Remember info?