繁体   English   中英

在WPF窗口中接收带有窗口消息的键盘事件(HwndSource.AddHook)

[英]Receive Keyboard Events with Window Messages in a WPF-Window (HwndSource.AddHook)

我有一个带有文本框的窗口。 光标在TextBox内部。 如果按某个键,则在WndProc中会收到一条消息(用于KeyUp和KeyDown)。 但是,如果我在KeyUp和KeyDown事件中将e.Handled设置为true,则不会收到任何关键消息:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        var textBox = new TextBox();
        textBox.KeyDown += TextBox_KeyDown;
        textBox.KeyUp += TextBox_KeyUp;
        Content = textBox;
        (PresentationSource.FromVisual(this) as HwndSource).AddHook(WndProc);
    }

    private void TextBox_KeyDown(object sender, KeyEventArgs e)
    {
        e.Handled = true;
    }

    private void TextBox_KeyUp(object sender, KeyEventArgs e)
    {
        e.Handled = true;
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        Debug.WriteLine(msg + " " + wParam);
        return IntPtr.Zero;
    }
}

在WndProc中是否可以接收PreviewKeyDown / PreviewKeyUp事件?

有很多方法可以拦截关键消息。 您甚至不需要任何库。 使用纯Win32 API可以,但是如果您想简化操作,请尝试处理ComponentDispatcherThreadPreprocessMessage事件:

ComponentDispatcher.ThreadPreprocessMessage += (ref MSG m, ref bool handled) => {
            //check if WM_KEYDOWN, print some message to test it
            if (m.message == 0x100)
            {
                System.Diagnostics.Debug.Print("Key down!");
            }
        };

该事件能够在实际发送到您的窗口之前接收任何关键消息。 因此,如果要处理原始消息(而不是处理PreviewKeyDown ,...),这就是您想要的。

AddHook方法允许为窗口添加一些挂钩过程,但实际上在WPF中受到限制(而WndProcForm WndProc受保护的等效方法可以拦截更多消息)。

尝试使用ManagedWinApi。 您可以使用NuGet安装它。

PM> Install-Package ManagedWinapi

有关键盘和其他味精拦截的广泛示例,请访问: http : //mwinapi.sourceforge.net/

另一种选择是https://easyhook.github.io/

这两个库都有据可查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM