There are times when the default behaviour of Windows Forms isn’t enough and you may need to hook a window procedure for another control and handle or peek at its messages.
So how do we subclass a managed control’s window?
Exactly the same way we subclass an unmanaged window, the only difference being that it requires a bit of Interop to marshal the pointers.
I have illustrated this with some snippets from a simple example that subclasses its parent Control although this can be any available control.
To start we’ll need an Interop class to encapsulate the Win32 function calls and types.
You’ll notice there are two versions of the SetWindowLong function. One in a nested class called MarshalToDelegate. This allows us to use it in different contexts and provide a descriptive syntax.
We need to add some fields to our class and an instance of the delegate we declared in the Interop class.
Now for our WindowProc. It has to be a static function.
Now we add some code that allows us to hook our WindowProc.
All that remains is to add the code to hook up our WindowProc at runtime and we can sneak a peek at all of the subclassed controls' WM_NOTIFY messages.
We initialise the delegate instance in the constructor then call HookWndProc() at a convenient point. I have done it in the override of OnParentChanged() as we can be sure our parent control is initialized at this point.
Unhooking can be problematic but as I take great pains to dispose of my classes explicitly then Dispose() is as good a place as any.
You’ll have to experiment with hooking to overrides or events called by your class to suit your own implementation.
This simple example only allows one way hooking at one point in program execution but you can easily be more sophisticated and provide for multiple controls and re-hooking etc. A similar approach can be applied to all of the windows callbacks.