Question

I have some questions regarding overriding the WndProc method of a Windows Form / NativeWindow.

What exactly is the difference between WndProc and DefWndProc (edit: I thought it is called "DefaultWndProc" before)? I can only override WndProc, but what is DefWndProc for, which I can call anytime?

And where to call base.WndProc in my overridden method? Or should I call DefWndProc instead? The following positions came into my mind:

protected override void WndProc(ref Message m)
{
    // 1st: I call the base handler at the start, in front of my handling.
    // Are there disadvantages here?
    base.WndProc(ref m);

    switch (m.Msg)
    {
        case (int)WindowsMessage.Paint:
            // 2nd: Do whatever you want to do now. I could also place
            // base.WndProc for each message manually here, at a point I
            // can control myself. It makes the method a little messy
            // since I have several base calls for each message I handle.
            base.WndProc(ref m);
            break;
        default:
            // 3rd: If I put it here, it never gets called for messages I
            // have handled. I think it is disastrous for specific
            // messages which need additional handling of the system.
            base.WndProc(ref m);
        }
    }
    // 4th: Or put it here. It gets called even after messages I have
    // already handled. If I made some drawings in WM_PAINT, doesn't
    // calling the system's default method draw "over" my paintings?
    // And is this really needed?
    base.WndProc(ref m);
}

What do you recommend? Is there a best-case-scenario or does it heavily depend on which messages I handle?

Was it helpful?

Solution

What exactly is the difference between WndProc and DefaultWndProc?

There is no method named "DefaultWndProc", I'll assume you are talking about DefWndProc. This question is difficult to answer since there is very little difference between the two. The DefWndProc() method corresponds to the way you write code in a language like C, the ability to call base.WndProc() is specific to .NET. They do the same thing, call the original window procedure of the window but with a small difference. The base.WndProc() method is capable of altering the message completely, DefWndProc() can only alter the Message.Result value. I can't think of a case where this matters.

The MSDN Library article for Control.WndProc() otherwise helps to remove the doubt, it stipulates that if you override the method then you should always use base.WndProc().

what is DefaultWndProc for, which I can call anytime?

Focusing on the "anytime" part of the phrase, this is very rarely the correct thing to do. You should almost always pinvoke SendMessage() to send a message to a window. Calling DefWndProc() should only ever be used if you intentionally want to bypass a custom WndProc() method. That is rare.

And where to call base.WndProc in my overridden method?

That depends on what you want to accomplish. There are three basic strategies:

  • Look at the m argument and implement your own custom behavior, then call base.WndProc(). This is the most common way and ought to be your default choice.
  • Call base.WndProc() first, then alter the m argument or execute code to customize the default processing of the message. This is appropriate for certain kind of messages, WM_NCHITTEST is the best example. Your WM_PAINT case is another one, if you need to paint on top of what was painted by the default window procedure then you have to do it this way.
  • Not call base.WndProc() at all. Appropriate if you completely customize the message handling and don't want to use the default behavior. Very common for filtering message, this is how KeyPressEventArgs.Handled works for example.

Exactly which bullet is appropriate requires insight in the way the message gets handled normally. This entirely depends on the specific control you derive from and the specific message so its impossible to give generic guidance. Getting it wrong however is almost always easy to diagnose.

OTHER TIPS

It depends on which messages you handle. base.WndProc just continues along as it was going to. So you can do any pre or post processing per message.

The way I use it is putting it on the end and just return the function whenever I don't want any further processing.

Differences between WndProc and DefWndProc are that WndProc processes the message (and when you override it including yours) while DefWndProc sends the message to the window so it does it's default interaction with the OS.

After WndProc is done, DefWndProc is called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top