Re: Using Pythonwin to poke at Windows apps?

From: Henrik Weber (Henrik.Weber_at_sdm.de)
Date: 03/11/04


Date: 11 Mar 2004 05:26:48 -0800

Thomas Heller <theller@python.net> wrote in message news:<mailman.177.1078844655.19534.python-list@python.org>...
> Henrik.Weber@sdm.de (Henrik Weber) writes:
>
> > Hello all,
> >
> > I'm trying to read information about widgets from running instances of
> > win32 applications. My current victim is the Explorer on a XP box. I'm
> > trying to access the menu bar. On XP this is not a standard menu but a
> > toolbar. So far I can retrieve a PyCWnd object with win32ui:
> >
> >>>> e = win32ui.FindWindow("ExploreWClass", None)
> >>>> w = win32ui.FindWindowEx(e, None, "WorkerW", None)
> >>>> w = win32ui.FindWindowEx(w, None, "ReBarWindow32", None)
> >>>> t = win32ui.FindWindowEx(w, None, "ToolbarWindow32", None)
> >>>> t = win32ui.FindWindowEx(w, t, "ToolbarWindow32", None)
> >>>> hex(t.GetSafeHwnd())
> '0x602d8'
> >>>> print t
> > object 'PyCWnd' - assoc is 01275A88, vi=<None>, notify=0,ch/u=0/0,
> > mh=0, kh=0
> >
> > I know that t now refers to a ToolbarWindow32 widget but seemingly
> > win32ui doesn't. Is there a way to get a PyCToolbar object from this?
>
> No idea.

I had hoped that there might be a way to cast or convert a PyCWnd
object to an object of a child class or to construct a PyCToolbar
object from an hwnd, something like that.

>
> > Or do I have to continue by sending messages? I tried sending a
> > TB_GETBUTTON message with win32gui.SendMessage, using a Python array
> > to reserve some memory for the TBBUTTON structure, but so far I have
> > only succeeded in crashing the Explorer. What would be the right way
> > to send a message that needs some memory to put the results into?
>
> If you go this way, ctypes is what you need. And Simon Bruning has
> written a series of articles which also might be helpful:
>
> http://www.brunningonline.net/simon/blog/archives/000652.html

Yes, I've read those articles. He does something similar to what I
want where he retrieves the content from an edit widget. My attempt
that I described above was inspired by this.

Now I've tried this with ctypes:

from ctypes import *
import win32ui, win32con

e = win32ui.FindWindow("ExploreWClass", None)
w = win32ui.FindWindowEx(e, None, "WorkerW", None)
w = win32ui.FindWindowEx(w, None, "ReBarWindow32", None)
t = win32ui.FindWindowEx(w, None, "ToolbarWindow32", None)
t = win32ui.FindWindowEx(w, t, "ToolbarWindow32", None)

class TBBUTTON(Structure):
    _fields_ = (("iBitmap", c_int),
                ("idCommand", c_int),
                ("fsState", c_byte),
                ("fsStyle", c_byte),
                ("bReserved", c_byte * 2),
                ("dwData", POINTER(c_long)),
                ("iString", c_char_p))

b = TBBUTTON()
f = windll.user32.SendMessageA
TB_GETBUTTON = win32con.WM_USER + 23
print f(t.GetSafeHwnd(), TB_GETBUTTON, 0, byref(b))

When I run it the first time I get a return value 1. However the
TBBUTTON structure contains mostly zeroes. Running it again crashes
the Explorer. Even if I open another Explorer the script will crash it
with every subsequent execution until the machine is rebooted.

So obviously I'm doing something wrong, but what?

Henrik