Subclass form window proc

  • Thread starter Thread starter Mike Scott
  • Start date Start date
M

Mike Scott

What's the easiest way to subclass the window proc of a form so that I can
add special processing for Windows messages such as WM_CLOSE?

Cheers,

MikeS.
 
The combination of MessageWindow and native dll that'd
redirect the subclassed messages to this MessageWindow...

-Alex
 
Guys,
Keep in mind that I haven't had a chance to update Callbacks library with
the ARM code for PPC 2003. If there are any takers, I would gladly
incorporate the new assembly stub into the article code.

Mark Erikson said:
What's the easiest way to subclass the window proc of a form so that I can
add special processing for Windows messages such as WM_CLOSE?

Cheers,

MikeS.

The other option is to use Alex Feinman's OpenNETCF.Callbacks library.
Since it's pretty much an all-managed code deal, this lets you put it
all inside your current program, rather than shipping an additional
DLL. See the article at
http://www.alexfeinman.com/Callbacks/Callbacks.htm for really detailed
information on how the technique works(the WndProc section is at the
bottom).

Here's some example code (mostly taken from Alex's sample). Hope it
helps!

Mark Erikson



Basic usage: call InitiateSubclass() in your form's constructor. Fill
in WndProc as usual.


using OpenNETCF.Callbacks;

[DllImport("coredll")]
public static extern IntPtr GetFocus();

[DllImport("coredll")]
public static extern int GetWindowLong(IntPtr hWnd, GetWindowLongParam
nItem);

[DllImport("coredll")]
public static extern void SetWindowLong(IntPtr hWnd, int
GetWindowLongParam, int nValue);

[DllImport("coredll")]
public static extern IntPtr CallWindowProc(IntPtr pfn, IntPtr hWnd,
int msg, IntPtr wParam, IntPtr lParam);


private Callback newWndProc;
private IntPtr oldWndProc;

int GWL_WNDPROC = -4;

private void InitiateSubclass()
{
this.Focus();
IntPtr hWnd = GetFocus();

if (hWnd == IntPtr.Zero)
throw new InvalidOperationException("Subclass error!");

newWndProc = CallbackFactory.AllocateCallback(this, "WndProc");
oldWndProc = new IntPtr(GetWindowLong(hWnd, GWL_WNDPROC));
Win32Window.SetWindowLong(hWnd, GWL_WNDPROC,
newWndProc.CB.ToInt32());
}

private void RemoveSubclass()
{
this.Focus();
IntPtr hWnd = GetFocus();

SetWindowLong(hWnd, GWL_WNDPROC, oldWndProc.ToInt32());
}


private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr
lParam )
{
// do all your usual message processing here
// to call the base WndProc, do the following:
// CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam);
}
 
Back
Top