我有一些关于覆盖 Windows
WndProc
/ Form
的 NativeWindow
方法的问题。
WndProc
和DefWndProc
到底有什么区别?我只能覆盖 WndProc
,但是 DefWndProc
是做什么用的,我可以随时调用它?
在我重写的方法中在哪里调用
base.WndProc
?或者我应该打电话给DefWndProc
?我想到了以下立场:
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);
break;
}
}
// 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);
}
你有什么推荐?是否有最好的情况,或者它是否很大程度上取决于我处理的消息?
WndProc 和 DefaultWndProc 到底有什么区别?
没有名为“DefaultWndProc”的方法,我假设您正在谈论DefWndProc。这个问题很难回答,因为两者之间几乎没有什么区别。 DefWndProc() 方法对应于用 C 等语言编写代码的方式,调用 base.WndProc() 的能力是 .NET 特有的。他们做同样的事情,调用窗口的原始窗口过程,但有一点小小的区别。 base.WndProc() 方法能够完全改变消息,DefWndProc() 只能改变 Message.Result 值。我想不出这有什么重要的案例。
Control.WndProc() 的 MSDN 库文章有助于消除疑虑,它规定如果重写该方法,则应始终使用 base.WndProc()。
DefaultWndProc 是做什么用的,我可以随时调用它?
专注于短语中的“随时”部分,这很少是正确的做法。您几乎应该始终调用 SendMessage() 以将消息发送到窗口。仅当您“有意”想要绕过自定义 WndProc() 方法时,才应使用 DefWndProc() 调用。这是很少见的。
在我的重写方法中在哪里调用base.WndProc?这取决于您想要完成什么。共有三种基本策略:
查看
m
m
top上绘制,那么你必须这样做。 根本不调用base.WndProc()。如果您完全自定义消息处理并且不想使用默认行为,则适用。对于过滤消息来说非常常见,这就是 KeyPressEventArgs.Handled 的工作原理。
我使用它的方式是将它放在最后,每当我不需要任何进一步处理时就返回该函数。
WndProc 和 DefWndProc 之间的区别在于,WndProc 处理消息(当您重写它(包括您自己的消息)时),而 DefWndProc 将消息发送到窗口,以便它执行与操作系统的默认交互。
WndProc 完成后,DefWndProc 被调用。