PyWin SendMessage

Thomas Heller theller at python.net
Thu Sep 29 14:05:07 EDT 2005


"g.franzkowiak" <g.franzkowiak at onlinehome.de> writes:

> Thomas Heller schrieb:
>> "g.franzkowiak" <g.franzkowiak at onlinehome.de> writes:
>> 
>> 
>>>Hello everybody,
>>>
>>>I've tryed to use an interprocess communication via
>>>SendMessage on Windows.
>>>Unfortunately, nothing goes on
>>>
>>>#########################################################################
>>>#! /usr/bin/env python
>>>
>>>import win32api, win32ui, win32con
>>>import struct, array
>>>
>>>"""
>>>typedef struct tagCOPYDATASTRUCT {  // cds
>>>    DWORD dwData;
>>>    DWORD cbData;
>>>    PVOID lpData;
>>>} COPYDATASTRUCT;
>>>"""
>>>
>>>def packCopyData(nNum, sString):
>>>    int_buffer  = array.array("L",[nNum])
>>>    char_buffer = array.array('c', sString)
>>>    int_buffer_address  = int_buffer.buffer_info()[0]
>>>    char_buffer_address = char_buffer.buffer_info()[0]
>>>    char_buffer_size    = char_buffer.buffer_info()[1]
>>>    copy_struct = struct.pack("pLp",        # dword*, dword, char*
>>>                              int_buffer_address,
>>>                              char_buffer_size,
>>>                              char_buffer)
>>>    return copy_struct
>> 
>> 
>> After packCopyData(...) returns, the arrays are destroyed, which will
>> probably void their contents.  You must keep them alive until you don't
>> need the COPYDATASTRUCT instance any longer.  For this kind of stuff,
>> ctypes may be easier to use than pywin32.
>> 
>> Thomas
>
> Hmm, have read something in <<http://aspn.activestate.com>>
> and the script changed to this:
>
> #---------------------------------------------------------
> #! /usr/bin/env python
>
> import win32api, win32ui, win32con, win32gui
> import struct, array
> from ctypes import *
>
> """
> typedef struct tagCOPYDATASTRUCT {  // cds
>     DWORD dwData;
>     DWORD cbData;
>     PVOID lpData;
> } COPYDATASTRUCT;
> """
>
> class COPYDATATYPE(Structure):
>     _fields_ = [("nNum",   c_ulong),
>                 ("szData", c_char_p)]
>
> class COPYDATASTRUCT(Structure):
>     _fields_ = [("dwData", c_ulong),
>                 ("cbData", c_ulong),
>                 ("lpData", POINTER(COPYDATATYPE))]
>
> # get the window handle
> hwnd = win32ui.FindWindow(None, "target window")
>
> # print just for fun
> # ##print hwnd
>
> # prepare copydata structure for sending data
> cpyData = COPYDATATYPE(1, '1')
> cds = COPYDATASTRUCT(c_ulong(1),
>                      c_ulong(sizeof(cpyData)),
>                      pointer(cpyData))
>
> # try to send a message
> win32api.SendMessage(hwnd,
>                      win32con.WM_COPYDATA,
>                      0,
>                      pointer(cds))
>
> #---------------------------------------------------------
> and the message for the last line is:
> ==> TypeError: an integer is required"
>
> This message comes with "pointer(cds)" and with "addressof(cds)"

That error refers to the first argument - win32ui.FindWindow returns a
PyCWnd object, which is not accepted by win32api.SendMessage.
Changing this brings you one step further.  win32api.SendMessage accepts
an integer for the last element, so addressof(cds) should work now.

win32gui.SendMessage is more tolerant in what it accepts as 4th
argument, according to the error message you get when you try it it
expects a string, a buffer, or an integer.  So you could use addressof()
or pointer(), what you like best.

Thomas



More information about the Python-list mailing list