views:

64

answers:

1

i am trying to use TTM_GETTEXT via SendMessage using pywin32. the problem is, the structure of the lparam, which is where the text should be stored, has to be TOOLINFO, which is well documented in MSDN, but has no counterpart in pywin32. is there a way to create the same structure using python and pywin32?

Edit: here's the code i came up with using ctypes. I made a Structure for TOOLINFO, created a buffer from it to pass to pywin32's SendMessage, then converted it back to the TOOLINFO ctypes Structure. Only problem is, it isn't working:

# My TOOLINFO struct:
class TOOLINFO(Structure):
  _fields_ = [("cbSize", UINT),
              ("uFlags", UINT),
              ("hwnd", HWND),
              ("uId", POINTER(UINT)),
              ("rect", RECT),
              ("hinst", HINSTANCE),
              ("lpszText", LPWSTR),
              ("lpReserved", c_void_p)]

# send() definition from PythonInfo wiki FAQs
def send(self):
  return buffer(self)[:]

ti = TOOLINFO()
text = ""
ti.cbSize = sizeof(ti)
ti.lpszText = text                 # buffer to store text in
ti.uId = pointer(UINT(wnd))        # wnd is the handle of the tooltip
ti.hwnd = w_wnd                    # w_wnd is the handle of the window containing the tooltip
ti.uFlags = commctrl.TTF_IDISHWND  # specify that uId is the control handle
ti_buffer = send(ti)               # convert to buffer for pywin32

del(ti)

win32gui.SendMessage(wnd, commctrl.TTM_GETTEXT, 256, ti_buffer)

ti = TOOLINFO()              # create new TOOLINFO() to copy result to

# copy result (according to linked article from Jeremy)
memmove(addressof(ti), ti_buffer, sizeof(ti))

if ti.lpszText:
  print ti.lpszText          # print any text recovered from the tooltip

Text isn't being printed, but i assumed that it should contain the text from the tooltip i want to extract from. Is there something wrong with how I used the ctypes? I am quite sure that my values for wnd and w_wnd are correct, so i must be doing something wrong.

+1  A: 

It's not particularly pretty, but you can use the struct module to pack the fields into a string with the appropriate endianess, alignment, and padding. It's a little tricky since you must define the structure with a format string using only corresponding fundamental data types in the correct order.

You could also use ctypes for defining structure types or also interfacing with the DLLs directly (rather than using pywin32). ctypes structure definitions are closer to C definitions, so you may like it better.

If you choose to use ctypes for structure defs along with pywin32, check out the following for a clue to how to serialize the structs into strings: How to pack and unpack using ctypes (Structure <-> str)

Jeremy Brown
`ctypes` look great, but i'm in too deep with pywin32 already to switch. but the struct module looks good too. i might go with the `struct` approach. thanks!
maranas