[python-win32] Trouble with SetWindowLong().

david.briant at ubs.com david.briant at ubs.com
Mon Jan 17 11:22:06 CET 2011


You can use PostThreadMessage instead of PostMessage.

To get the address of a python WndProc I use ctypes:

WNDPROC = WINFUNCTYPE(c_int, c_ulong, c_ulong, c_ulong, c_ulong)

lpfnwndproc = WNDPROC(wndproc)

where:

def wndproc(hWnd, Msg, wParam, lParam):
    ...


I intercept WM_QUIT for shutdown - I believe WM_CLOSE is just for a
window

my message pump looks like this:

        msg = MSG()
        lpmsg = byref(msg)
        while 1:
            ret = user32.GetMessageA(lpmsg, 0, 0, 0)
            if ret == -1:
                raise WinError()
            elif ret == 0:
                return # got WM_QUIT
            if not self.filter_message(lpmsg):
                user32.TranslateMessage(lpmsg)
                user32.DispatchMessageA(lpmsg)


HTH

David




-----Original Message-----
From: python-win32-bounces+david.briant=ubs.com at python.org
[mailto:python-win32-bounces+david.briant=ubs.com at python.org] On Behalf
Of Tim Golden
Sent: Sun 16-Jan-2011 16:42
Cc: python-win32 at python.org
Subject: Re: [python-win32] Trouble with SetWindowLong().

On 16/01/2011 2:51 PM, Ben Timby wrote:
> IIUC, WndProc receives messages from the message pump. I am attempting
> to override the default message handler with my own. The code I posted
> is a contrived example. So really, I am not interested in the
> correctness of it, but why does the call to SetWindowLong() fail the
> way it does when I call it.

OK: because the parameters to the win32api.SetWindowLong
function are (cut-and-pasted and lightly reformatted from the docs):

"""
hwnd : int - The handle to the window.

offset : int - Specifies the zero-based byte offset of the value to
change.
Valid values are [.. snipped ...] or one of the GWL_ constants.

val : int - Specifies the long value to place in the window's reserved
memory.
"""

The MSDN docs at:

   http://msdn.microsoft.com/en-us/library/ms633591%28v=vs.85%29.aspx

give for the "offset param":

"""
GWL_WNDPROC - Sets a new address for the window procedure.
You cannot change this attribute if the window does not belong
to the same process as the calling thread.

[... snip ...]

If you use SetWindowLong with the GWL_WNDPROC index to replace
the window procedure, the window procedure must conform to the
guidelines specified in the description of the WindowProc callback
function.
"""

and there's some extra stuff about the GWL_WNDPROC as well which I've
missed.


> Here is a good one:
> http://wiki.wxpython.org/HookingTheWndProc

OK. Well I have to apologise because I hadn't appreciated how
much work the win32 modules are doing behind the scenes on this
one. They generally just wrap Win32 API calls fairly directly.

On the other hand, you do have a couple of issues:

1) You're using the win32api version of SetWindowLong. The win32gui
version -- which your linked example uses -- does in fact do some
jiggery-pokery with the final parameter if the "offset" param is
GWL_WNDPROC. Without that extra work by win32gui, the first one
is trying to convert your Python function object into a pointer-ish
value (such as an integer) which it can then pass directly to the
underlying API call.

2) The first parameter is a *window* handle, not a process handle.
Now, in your initial post, you've given no suggestion that you're
even operating inside a windowed context, so I was suprised to find
you trying to replace the underlying Windows message-handling proc.

So, sorry if I came across a bit brusquely, but if you'd posted
the link to the example in the first place and given a little
bit of context I'd have been able to give a better answer up-front.

Obviously, the callable you pass in should have the signature of
a Windows proc, as in the example you linked to. I'm not sure
whether it will complain if it doesn't or whether it will merely
fall over in a big heap. Feel free to find out and let us know!

In short, then:

1) Use the win32gui version of SetWindowLong
2) Pass a valid window handle (from within the same process as your
code) as the first param
3) Pass a suitable function as the third param

and, hopefully, all should be well.  (Famous Last Words...)

TJG
_______________________________________________
python-win32 mailing list
python-win32 at python.org
http://mail.python.org/mailman/listinfo/python-win32
Visit our website at http://www.ubs.com 

This message contains confidential information and is intended only 
for the individual named. If you are not the named addressee you 
should not disseminate, distribute or copy this e-mail. Please 
notify the sender immediately by e-mail if you have received this 
e-mail by mistake and delete this e-mail from your system. 

E-mails are not encrypted and cannot be guaranteed to be secure or 
error-free as information could be intercepted, corrupted, lost, 
destroyed, arrive late or incomplete, or contain viruses. The sender 
therefore does not accept liability for any errors or omissions in the 
contents of this message which arise as a result of e-mail transmission. 
If verification is required please request a hard-copy version. This 
message is provided for informational purposes and should not be 
construed as a solicitation or offer to buy or sell any securities 
or related financial instruments. 

UBS Limited is a company limited by shares incorporated in the United 
Kingdom registered in England and Wales with number 2035362. 
Registered office: 1 Finsbury Avenue, London EC2M 2PP.  UBS Limited 
is authorised and regulated by the Financial Services Authority. 

UBS AG is a public company incorporated with limited liability in 
Switzerland domiciled in the Canton of Basel-City and the Canton of 
Zurich respectively registered at the Commercial Registry offices in 
those Cantons with Identification No: CH-270.3.004.646-4 and having 
respective head offices at Aeschenvorstadt 1, 4051 Basel and 
Bahnhofstrasse 45, 8001 Zurich, Switzerland.  Registered in the 
United Kingdom as a foreign company with No: FC021146 and having a 
UK Establishment registered at Companies House, Cardiff, with No:  
BR 004507.  The principal office of UK Establishment: 1 Finsbury Avenue, 
London EC2M 2PP.  In the United Kingdom, UBS AG is authorised and 
regulated by the Financial Services Authority.

UBS reserves the right to retain all messages. Messages are protected 
and accessed only in legally justified cases. 


More information about the python-win32 mailing list