FW: Win32all documentation?

David Bolen db3l at fitlinxx.com
Mon Dec 10 16:55:08 EST 2001


David Brady <daves_spam_dodging_account at yahoo.com> writes:

> Um... yes, though I may be splitting hairs.  I've got
> a pretty solid grasp of Python in general, and I've
> been programming Windows in C/C++ for nearly 10 years.
>  The part I don't understand clearly is win32all
> *itself*.  I know *how* to enumerate windows in C; I
> just don't know how to get there from Python.

Hmm, if you've been programming Windows in C/C++ for that long, you
may just be working too hard to try to find something unique about the
"Python" solution. :-)

The win32all package is a thin wrapper over the Win32 API.  So your
answer to the question of how to do it in Python would be the same
(almost identical) to how to do it in C/C++.

The documentation included with win32all will highlight any slight
differences in the wrapping of a single function, and there are some
general conventions (e.g., "out" parameters in a Win32 API are
returned as part of a result tuple) that you'll get used to quickly.

So, given that you know how to enumerate Windows in C (e.g., using
EnumWindows), that's how you do it in Python with win32all - in this
case by using win32gui.EnumWindows, which has the same function
signature as the Win32 API version (callback and application value)
except that the win32all docs will note that the callback is a normal
Python function, and the application value can be any Python object
(not just an integer value as in the Win32 API).

But that's what it means to be a "thin" wrapper - there's pretty much
a one to one correspondence between wrapper functions in the win32all
modules and the underlying API.

It's not a completely exhaustive wrapping, but a large percentage of
the API is wrapped.  For those cases where they aren't, sometimes the
calldll package (a lower level interface) can be used instead, or if
you can find a system COM object, then you can use a COM interface
instead.

> Over the weekend I walked through the entire win32all
> installation and found a lot of demos, many of which
> appear to be most illuminating.  But they still only
> shine points of light in a dark corner, and I want to
> turn on the Big Light Overhead.  If there were
> win32all documentation somewhere, something at least
> as complete as the documentation like the Python
> module dox
> (http://www.python.org/doc/current/modindex.html), I
> would be in fat city.

There isn't, but that's largely because it would just be redundant
with the Win32 API documentation.  (Although I'm sure any
contributions to the existing win32all documentation would be welcome)

> I own Mark's book, and I've read most of it.  While it
> is excellent, it doesn't provide a reference so much
> as a lot more in-depth examples.  For example, filling
> out and printing a Microsoft Word template document
> using win32com is demonstrated, but no further data is
> forthcoming on what *else* you can do with MS Word
> from win32com.  Like, for example, how to open Word to
> a blank document and create and format a documnt from
> scratch.

But that's not something that win32all needs to document, because
Microsoft already provides extensive documentation for the Word object
model, including online help files (which you can optionally install
right from the Word/Office installation CD - VBAWRD9.CHM or
VBAWD10.CHM depending on version). win32com is just a COM interface
from Python - what you can do over it is anything you can do over a
COM exported interface in general.

In this case, your question is really 90% Word related (its object
model) and maybe 10% Python (how to talk to any old COM object).

BTW, this is precisely an area where I also wanted the "Big Light
Overhead" when I first ventured into it a while back.  What I found
out was that the big light was immersing myself in the MS Office
object model for a bit, since Python was really just a user of the
establishment for this bit of work.

The office developer object model is something you can choose to
install with a local MSDN installation (it's under the Office
Developer Documentation topic).  It's also available on the web - I'm
not sure how to create a direct shortcut, but if you start at the MSDN
library (http://msdn.microsoft.com/library) and then navigate down
through "Office Solutions Development", "Microsoft Office Developer"
and then "Microsoft Office 2000 (or XP) Developer" you'll find the
object model guide, which will include Word among the other
applications.  There are probably books written on the subject too
(doubtless those kinds whose authors seem to get paid by weight).

>           If I could just see all the methods, objects
> and classes of win32all, I could probably figure out
> how to hook up the rest of the stuff I need.

But you're not asking for methods, objects and classes of _win32all_
here, you're asking for methods, objects and classes of _MS Word_,
which is going to be documented over with Word.

This is no different than asking how to automate Word from VBScript,
or VB for that matter.  Those languages have mechanisms to access COM
objects, but they don't document all the objects they can reach -
that's up to each object to do on its own.  The object model is common
to all languages, Python included.

> Forgive me if I'm sounding whiny.  I'm beating my head
> against a brick wall here, and I'm willing to admit
> it's my head's fault... if someone will just show me
> the door in the wall to walk through.  In defense of
> my head, however, the wallbuilder and doormaker might
> consider marking the door more clearly.  (Unless
> they're sickos who enjoy this sort of thing.  :-)

I hope this is helping to clarify things somewhat, but I'm willing to
help you keep trying to break through to clarity :-)

It seems like you may be thinking a little too deeply about the Python
support.  If instead you treat the win32all package modules as
interfaces into the existing Windows support (whether direct Win32 API
or COM objects) and then use the common documentation for the
facilities being accessed, you might have an easier time using the
Python-specific documentation just to highlight Python-unique aspects.

> I know from MSDN, for example, how to enumerate all
> the windows in the system and how to get and change
> the caption of a window.  For this portion of our
> program, I am asking how to do it from Python.  If
> there isn't a "win32.enumeratewindows" method, then
> how can I call the windows API functions FindWindow()
> and EnumWindows()?  I do not see them listed when I do
> a dir(win32api):
(...)
> ...I infer from my reading that the win32api functions
> of Python are considered fairly complete, so I'm
> willing to assume that these functions are missing
> because I'm looking in the wrong place, or that
> they're implemented in a more Python-friendly way
> altogether and using the api in this case is a poor
> choice.  If someone would please show me how these
> ruby slippers worked, I'm sure I could go home....

Ah, this might be one of the roots of your problem.  The win32all
package is a collection of modules - win32api is but one of about a
dozen.  The online help will show them all in the module list, and you
can use the index to search by function.  They're divided to avoid
having to load everything into every application, and after working
with it for a little while, you'll find it pretty easy to pick which
module a function is likely in.

In your case, FindWindow/Ex() and EnumWindows() are in the win32gui
module.

There's also two modules (win32ui and win32uiole) that are part of the
"Pythonwin" directory (not win32) which have their own documentation
file.

> So, 3 things:
> - How to find an application running in the system,
> preferrably by window class, and activate one of its
> child windows, which may be positioned randomly on the
> screen.  There may be multiple instances of the window
> class running, I'd like to be able to inspect them to
> be able to pick the correct one.
> - How to send mouse actions to a window.
> - How to capture a screenshot of a window.

Note that while you could probably build something for this, would you
also be willing to just use a dedicated test tool for the process?
Personally, I tend to use something like AutoIt, and just run it from
beneath my Python script (either as a standalone executable, or via
its COM interface) if I need scripting over and above the interactive
work.

I can't be as specific as I'd like on building it in Python since I
haven't needed to do this specific operations myself (neither in
Python nor C/C++).  It doesn't look like the SendInput() API function
is wrapped (although maybe you could fake it with SendMessage()) so
that would make it tricky, although as others have pointed out you
could invoke a WSH object (via win32com) to use SendKeys().  But I've
also found in the past that properly scripting (simulating a user)
your way through something often gets tricky and a good standalone
utility can help out a lot.

As for capturing the screenshot, there are the standard DC and bitmap
(e.g., BitBlt) functions in win32ui which should be able to do what
you want.  E.g., grab a DC for the desktop or window you are
interested in, and then BitBlt its contents to an in-memory bitmap.
While I haven't tried it, I would expect that the PIL package might be
helpful past that point in terms of manipulating the bitmap, storing
it or whatever.

> 2. Whenever I install or reinstall an operating
> system, I have about 20 different applications that
> have to be installed and have their registration codes
> entered.  The process AFTER the OS is installed takes
> about four hours.  I'd like a script that launches
> their installers, clicks through their install
> interfaces, and types in my user and registration info
> automatically.  In this way, I could fire up a new
> machine, launch the script, and let it install and
> register my software, rebooting as necessary.  Once
> that's done, I usually reorganize the Programs folder
> inside the Start Menu so that I can more easily
> navigate it by keyboard (for example, renaming the
> 4,219,376 applications whose names start with
> "Microsoft" so that hitting "O" launches Office and
> "W" launches Word.

This also seems doable with a dedicated user simulation tool such as
AutoIt directly, at least other than the reboot part, since that
complicates things.  Renaming of the folders is probably easiest by
just renaming the various files in the filesystem.

For an internal installation tool we have (which is in Python) we
manage across the reboot using the standard autologon and autorun
Windows keys to restart our application, and we keep persistent state
in a pickled file to resume following the reboot.  So you could do
something like that and just use an AutoIt-like tool for the actual
operations.

> Three things, again:
> 1 - Finding the start menu folder so the script can
> put itself there to continue running after each
> reboot.

Well, either that or just use the autologon and autorun keys so that
it executes automatically when the system restarts.

> 2 - Launching an app and then monitoring it, waiting
> for it to die.

If it's an executable, you can launch it with os.system() or
os.startfile() in Python >= 2.0.  The former wouldn't return until the
command had completed so that could be an implicit monitor (put into a
separate thread if you wanted to keep working while waiting).

> 3 - Walking through the start menu shortcuts and
> renaming them.

If it's en-masse, you might actually be best served with filesystem
operations at that level.  I'm not positive if there's a guaranteed
way to locate the shortcut files that is system-independent (e.g.,
they're located differently under NT than Win9x) although others may
have a suggestion on that front.

But once you know the location, normal os functions to enumerate the
directory (e.g., os.listdir()) and rename files (os.rename()) may be
all you need.

> -dB
> P.S. Bonus question.  How can I change the desktop
> background image in Win32 from Python?  Thanks again!
> P.P.S. No disrespect is intended towards Hammond &
> Robinson, their book, or their documentation as
> presented on the ActiveState site.  I'm having
> difficulty, yes, but I'm grateful I've got as much
> information as I do.

Hmm, that's another thing I haven't had to do myself (even in C/C++)
but if you have a hint as to what you'd do in C/C++ I might guess at a
Python approach.  A quick MSDN search seems to point to
SystemParametersInfo() with SPI_SETDESKTOPWALLPAPER which doesn't seem
to be wrapped in a win32all module, but which you could probably use
the calldll package to call.  I'm not entirely sure how it interacts
with an ActiveX desktop though?

--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list