WinForms等效于WPF的WindowInteropHelper、HwndSource、HwndSourceHook

5

我有这样一段代码:

IntPtr hWnd = new WindowInteropHelper(this).Handle;
HwndSource source = HwndSource.FromHwnd(hWnd);
source.AddHook(new HwndSourceHook(WndProc));
NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, NativeMethods.WM_CALL, IntPtr.Zero, IntPtr.Zero);

这原本是一个WPF应用程序。然而,我需要在WinForms应用程序中复制该功能。此外,NativeMethods.PostMessage只是映射到user32.dll PostMessage:

[DllImport("user32")]
public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

在我的WinForms应用程序中,是否有可以使用的WindowInteropHelper/HwndSource/HwndSourceHook的一对一等效物?


1
只需覆盖WndProc()方法即可。 - Hans Passant
2个回答

5
基本要点是:你只需要从源代码中获取AddHook。每个WinForm都有一个方法GetHandle(),它会给你窗口/表单的句柄(而你已经自己找到了PostMessage)。
要翻译AddHook,你可以编写自己的类实现IMessageFilter(1),或者覆盖WndProc()(2)。
(1)将接收应用程序范围内的消息,无论您将其发送到哪个窗体,而(2)仅接收覆盖该方法的特定窗体的消息。
我找不到关于WM_CALL的任何信息,因为您必须将窗口消息指定为整数(通常是十六进制),所以这取决于您。
(1):
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public partial class Form1 : Form
{
    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

    //private const int WM_xxx = 0x0;
    //you have to know for which event you wanna register

    public Form1()
    {
        InitializeComponent();

        IntPtr hWnd = this.Handle;
        Application.AddMessageFilter(new MyMessageFilter());
        PostMessage(hWnd, WM_xxx, IntPtr.Zero, IntPtr.Zero);
    }        
}

class MyMessageFilter : IMessageFilter
{
    //private const int WM_xxx = 0x0;

    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_xxx)
        {
            //code to handle the message
        }
        return false;
    }
}

(2):

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public partial class Form 1 {
    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

    //private const int WM_xxx = 0x0;
    //you have to know for which event you wanna register

    public Form1()
    {
        InitializeComponent();

        IntPtr hWnd = this.Handle;
        PostMessage(hWnd, WM_xxx, IntPtr.Zero, IntPtr.Zero);
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WMK_xxx)
        {
            //code to handle the message
        }
    }
}

你的回答节省了我很多时间,谢谢!非常出色。 - Dan Bechard

2

我不是WPF方面的专家,但对我来说,你似乎正在寻找NativeWindow


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接