WinForms 等效于 WPF WindowInteropHelper、HwndSource、HwndSourceHook

Posted

技术标签:

【中文标题】WinForms 等效于 WPF WindowInteropHelper、HwndSource、HwndSourceHook【英文标题】:WinForms equivalent of WPF WindowInteropHelper, HwndSource, HwndSourceHook 【发布时间】:2013-12-05 01:05:23 【问题描述】:

我有一段代码,例如:

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 吗?

【问题讨论】:

只需覆盖 WndProc() 方法。 【参考方案1】:

基本点是:除了来自源的AddHook 之外,您不需要任何东西。每个 WinForm 都有一个方法 GetHandle(),它将为您提供 Window/Form 的句柄(您已经自己找到了 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
        
    

【讨论】:

您的回答为我节省了很多时间,谢谢!!工作出色。【参考方案2】:

我不是更多的 WPF 背景。但对我来说,听起来你正在寻找NativeWindow。

【讨论】:

以上是关于WinForms 等效于 WPF WindowInteropHelper、HwndSource、HwndSourceHook的主要内容,如果未能解决你的问题,请参考以下文章

WPF等效于Application.AddMessageFilter(Windows窗体)

WPF 图像的单击事件

等效于使用 c# wpf 的 IsDisposed [重复]

WinForms 或 WPF 的文本差异可视化控件

等效于 Avalonia 的应用程序设置

如何在 Jetbrains Rider 中开发 GUI 设计器,例如在 Visual Studio 中用于 WinForms、WPF 等? [复制]