【问题标题】:Why would you override wndproc你为什么要覆盖 wndproc
【发布时间】:2015-05-21 15:56:11
【问题描述】:
我一直在环顾四周,并没有真正看到太多关于为什么有人会覆盖 wndproc 来处理消息的信息。
所以我想知道:
为什么要这样做?
什么时候做?
它在 C# 中的一般用途是什么?
当看到从计算机插入和拔出串行 COM 时,我尝试使用它,但我觉得我更好地依赖于我自己创建的方法。
我看到的其他消息是关于按键、光标设置和其他各种操作的。话虽这么说,这些东西中的大多数已经在 c# 库中内置了方法。所以我再次回到我的三个主要问题。任何信息、意见、示例等都会很棒。
【问题讨论】:
标签:
c#
overriding
wndproc
【解决方案1】:
WndProc() 是 Windows 窗口工作方式的核心。它是一个围绕 window procedure 的托管包装方法,该函数在过去是用 C 语言编写的。这是您自定义窗口行为的方式,使其对操作系统或其他程序生成的通知做出不同的响应。
您通常不需要重写它,基类中的 WndProc() 方法处理大部分基本通知。将它们转换为友好的 .NET 事件,例如 Click 等。但这并不完整,因为通知太模糊或必然如此,因为它不知道有关自定义窗口使用的消息的任何信息。在这种情况下,您可以依靠覆盖 WndProc() 来拦截消息。我能想到的最好的例子是创建一个无边框窗口来绘制一个自定义窗口框架,并且仍然给窗口正常的行为。最容易通过拦截 WM_NCHITTEST 之类的消息来完成,而不是由 .NET 包装。
真正了解 WndProc() 需要阅读 Petzold 的开创性著作“Programming Windows”。也许今天不再那么容易掌握了,它确实假设对 C 语言有基本的了解。这是 30 年前 winapi 所针对的语言,当时面向对象的语言没有被广泛使用或可用。这也解释了为什么在 WndProc() 中编写代码相当痛苦,几乎没有抽象,而且你不能真正忽略指针。
Microsoft 确实从 Windows 8 和 WinRT api 开始努力将其淘汰。不完全是灌篮高手,也许 Windows 10 会给它一些牵引力。使 WinRT 在后台运行的基础技术是 COM,它比 C 语言进步了一大步,因为它可以支持对象模型。尽管它很好地隐藏在友好的语言预测中,但 COM 编程是大多数程序员会尽量避免的:)
【解决方案2】:
我发现它对于处理 UserControl 的按键事件很有用。
keypress、keyDown 或 KeyUp 事件在响应用户控件时非常挑剔(即使 KeyPreview 设置为 true 等等)。我发现,如果我覆盖 WndProc(),我在控制处理命令时会更加可靠。