如何在WPF中处理WndProc消息?

Shu*_*uft 106 c# wpf wndproc

寻找WPF陡峭的学习曲线.

在好的Windows窗体中,我只是覆盖WndProc,并在它们进入时开始处理消息.

有人能告诉我如何在WPF中实现同样的事情吗?

Rob*_*ean 131

您可以通过System.Windows.Interop包含名为的类的命名空间来完成此操作HwndSource.

使用它的例子

using System;
using System.Windows;
using System.Windows.Interop;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WndProc);
        }

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            // Handle messages...

            return IntPtr.Zero;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

完全取自优秀博客文章:在Steve Rands的WPF应用程序中使用自定义WndProc

  • @ Mo0gles - 仔细想想你的问题,你会得到答案. (6认同)
  • @Mo0gles 没有在屏幕上绘制且用户可见的窗口?是的。这就是为什么有些程序有奇怪的空窗口,如果程序的状态损坏,这些窗口有时会变得可见。 (2认同)

Nol*_*rin 58

实际上,据我所知,这样的事情确实可以在WPF中使用HwndSourceHwndSourceHook.请参阅MSDN上的这个线程作为一个例子.(下面包括相关代码)

// 'this' is a Window
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(WndProc));

private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    //  do stuff

    return IntPtr.Zero;
}
Run Code Online (Sandbox Code Playgroud)

现在,我不太清楚你为什么要在WPF应用程序中处理Windows Messaging消息(除非它是使用另一个WinForms应用程序的最明显的互操作形式).在WPF和WinForms中,API的设计思想和性质是非常不同的,所以我建议你更熟悉WPF,以确切了解为什么没有WndProc的等价物.

  • 好吧,USB Device(dis)连接事件似乎正在通过这个消息循环,所以知道如何从WPF连接并不是一件坏事 (44认同)
  • @Noldorin:你能不能提供一些参考资料(文章/书籍),可以帮助我理解"设计思想和API的性质在WPF中与WinForms非常不同,...为什么没有WndProc的等价物"? (7认同)
  • 事实上,许多(大多数?)WPF应用程序都在标准桌面Windows上运行.WPF架构选择不公开Win32的所有底层功能是故意微软的,但仍然讨厌处理.我正在构建一个仅针对桌面Windows的WPF应用程序,但是与@flq提到的USB设备集成,接收设备通知的唯一方法是访问消息循环.有时打破抽象是不可避免的. (3认同)
  • 例如,“ WM_MOUSEWHEEL”,可靠地捕获那些消息的唯一方法是在WPF窗口中添加“ WndProc”。这对我有用,而官方的“ MouseWheelEventHandler”根本无法按预期工作。我无法正确地排列正确的WPF速球,无法通过`MouseWheelEventHandler`获得可靠的行为,因此需要直接访问`WndProc`。 (2认同)

sof*_*erx 15

HwndSource src = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
src.AddHook(new HwndSourceHook(WndProc));


.......


public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{

  if(msg == THEMESSAGEIMLOOKINGFOR)
    {
      //Do something here
    }

  return IntPtr.Zero;
}
Run Code Online (Sandbox Code Playgroud)