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@python.org http://mail.python.org/mailman/listinfo/python-win32