PyWin SendMessage

g.franzkowiak g.franzkowiak at onlinehome.de
Fri Sep 30 12:44:10 EDT 2005


Gonzalo Monzón schrieb:
> g.franzkowiak escribió:
> 
>> Thomas Heller schrieb:
>>  
>>
>>> "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
>>>   
>>
>>
>> Super, operates :-))
>>
>> My last answer must be in the Nirvana, strange ?
>>
>> Ok, only the version with 'addressof' generates a message and I must
>> play with the data types. The receiver becomes a wrong data formate.
>> Expect  (int=1, char[256]='1\00'), but the int is 0x31 and the string
>> somewhat. Must play with my data.
>>
>> Thanks
>> gerd
>>  
>>
> 
> Hi Gerd,
> 
> I'm not really sure of, but I think you must use a message value in
> range of WM_USER or WM_APP so this fact maybe let the receiver window
> getting bad data... have a look to this:
> 
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesmessages/wm_user.asp
> 
> 
> 0 through WM_USER
> <http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesmessages/wm_user.asp>
> 0x0400
>     Messages reserved for use by the system.
> *WM_USER* through 0x7FFF     Integer messages for use by private window
> classes.
> *WM_APP* through 0xBFFF     Messages available for use by applications.
> 0xC000 through 0xFFFF     String messages for use by applications.
> Greater than 0xFFFF     Reserved by the system.
> 
> 
> 
> I've done the same with PHP GTK and achieved random results sending low
> Msg values... until used WM_USER and above. Also, in my case only
> PostMessage work fine... try using both... but expect this doesn't
> happen with python,
> 
> Hope it helps.
> 
> Gonzalo


Hi Gonzalo,

thank you for your interest and for your tips.
With your links was it possible to learn something over messages in user
applications. I'm not the windows guru, like the open source scene.

My problem was not the message type and I think the WM_COPYDATA is the
right thing for interprocess communication between python and C++.
I've changed in my script the COPYDATATYPE field szData from c_char_p to
c_char * 256 and the memory is correct initialized. The first situation
was according to **data and in consequence the wrong content on the
receiver side.
Now is it a good thing :-)

gerd




More information about the Python-list mailing list