如何在WPF中处理WndProc消息?
在 Windows 窗体中,我只需重写 WndProc
,并开始处理传入的消息。
有人可以向我展示如何在 WPF 中实现相同功能的示例吗?
In Windows Forms, I'd just override WndProc
, and start handling messages as they came in.
Can someone show me an example of how to achieve the same thing in WPF?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您可以通过包含名为
HwndSource
的类的System.Windows.Interop
命名空间来执行此操作。使用示例
完全取自优秀的博客文章:在 WPF 应用程序中使用自定义 WndProc,作者:Steve Rands
You can do this via the
System.Windows.Interop
namespace which contains a class namedHwndSource
.Example of using this
Completely taken from the excellent blog post: Using a custom WndProc in WPF apps by Steve Rands
实际上,据我了解,在 WPF 中使用
HwndSource
和HwndSourceHook
确实可以实现这样的事情。 请参阅MSDN 上的此主题< /a> 为例。 (相关代码如下)现在,我不太确定为什么要在 WPF 应用程序中处理 Windows Messaging 消息(除非它是与另一个 WinForms 应用程序一起使用的最明显的互操作形式)。 WPF 的设计思想和 API 性质与 WinForms 非常不同,因此我建议您更多地熟悉 WPF,以了解为什么没有 WndProc 的等效项。
Actually, as far as I understand such a thing is indeed possible in WPF using
HwndSource
andHwndSourceHook
. See this thread on MSDN as an example. (Relevant code included below)Now, I'm not quite sure why you'd want to handle Windows Messaging messages in a WPF application (unless it's the most obvious form of interop for working with another WinForms app). The design ideology and the nature of the API is very different in WPF from WinForms, so I would suggest you just familiarise yourself with WPF more to see exactly why there is no equivalent of WndProc.
如果您不介意引用 WinForms,则可以使用更面向 MVVM 的解决方案,该解决方案不将服务与视图耦合。 您需要创建并初始化一个System.Windows.Forms.NativeWindow,它是一个可以接收消息的轻量级窗口。
使用 SpongeHandle 注册您感兴趣的消息,然后重写 WndProc 来处理它们:
唯一的缺点是您必须包含 System.Windows.Forms 引用,但除此之外,这是一个非常封装的解决方案。
If you don't mind referencing WinForms, you can use a more MVVM-oriented solution that doesn't couple service with the view. You need to create and initialize a System.Windows.Forms.NativeWindow which is a lightweight window that can receive messages.
Use SpongeHandle to register for messages you're interested in and then override WndProc to process them:
The only downside is that you have to include System.Windows.Forms reference, but otherwise this is a very encapsulated solution.
以下是使用行为覆盖 WindProc 的链接:
http: //10rem.net/blog/2010/01/09/a-wpf-behavior-for-window-resize-events-in-net-35
[编辑:迟到总比不到好]下面是我的基于实现在上面的链接上。 尽管重新审视这一点,我还是更喜欢 AddHook 实现。 我可能会转向那个。
就我而言,我想知道窗口何时调整大小以及其他一些事情。 此实现连接到 Window xaml 并发送事件。
Here is a link on overriding WindProc using Behaviors:
http://10rem.net/blog/2010/01/09/a-wpf-behavior-for-window-resize-events-in-net-35
[Edit: better late than never] Below is my implementation based on the above link. Although revisiting this I like the AddHook implementations better. I might switch to that.
In my case I wanted to know when the window was being resized and a couple other things. This implementation hooks up to the Window xaml and sends events.
您可以附加到内置 Win32 类的“SystemEvents”类:
在 WPF 窗口类中:
You can attach to the 'SystemEvents' class of the built-in Win32 class:
in a WPF window class:
有多种方法可以在 WPF 中使用 WndProc 处理消息(例如使用 HwndSource 等),但通常这些技术是为与无法直接通过 WPF 处理的消息进行互操作而保留的。 大多数 WPF 控件甚至不是 Win32(以及扩展的 Windows.Forms)意义上的窗口,因此它们没有 WndProcs。
There are ways to handle messages with a WndProc in WPF (e.g. using a HwndSource, etc.), but generally those techniques are reserved for interop with messages that can't directly be handled through WPF. Most WPF controls aren't even windows in the Win32 (and by extension Windows.Forms) sense, so they won't have WndProcs.
WPF 不能在 WinForms 类型 wndprocs 上运行。
您可以在适当的 WPF 元素中托管 HWndHost,然后覆盖 Hwndhost 的 wndproc,但据我所知,这已经是您想要的最接近的结果。
http://msdn.microsoft.com/en-us/library/ms742522。 aspx
http://blogs.msdn.com /nickkramer/archive/2006/03/18/554235.aspx
WPF doesn't operate on WinForms type wndprocs
You can host an HWndHost in an appropriate WPF element then override the Hwndhost's wndproc, but AFAIK that's as close as you're going to get.
http://msdn.microsoft.com/en-us/library/ms742522.aspx
http://blogs.msdn.com/nickkramer/archive/2006/03/18/554235.aspx
简短的回答是你不能。 WndProc 的工作原理是将消息传递到 Win32 级别的 HWND。 WPF 窗口没有 HWND,因此无法参与 WndProc 消息。 基本 WPF 消息循环确实位于 WndProc 之上,但它将它们从核心 WPF 逻辑中抽象出来。
您可以使用 HWndHost 并获取 WndProc。 然而,这几乎肯定不是您想要做的。 对于大多数用途,WPF 不对 HWND 和 WndProc 进行操作。 您的解决方案几乎肯定依赖于在 WPF 中而不是在 WndProc 中进行更改。
The short answer is you can't. WndProc works by passing messages to a HWND on a Win32 level. WPF windows have no HWND and hence can't participate in WndProc messages. The base WPF message loop does sit on top of WndProc but it abstracts them away from core WPF logic.
You can use a HWndHost and get at a WndProc for it. However this is almost certainly not what you want to do. For the majority of purposes, WPF does not operate on HWND and WndProc. Your solution almost certainly relies on making a change in WPF not in WndProc.