在WPF窗口中接收带有窗口消息的键盘事件(HwndSource.AddHook) [英] Receive Keyboard Events with Window Messages in a WPF-Window (HwndSource.AddHook)

查看:849
本文介绍了在WPF窗口中接收带有窗口消息的键盘事件(HwndSource.AddHook)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Window with a TextBox. The cursor is inside the TextBox. If I press a key, then I receive a message in WndProc (for KeyUp and KeyDown). But if I set e.Handled = true in the KeyUp and KeyDown events, then I don't receive any key messages:

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事件?

Is it possible to receive a PreviewKeyDown/PreviewKeyUp event in WndProc?

推荐答案

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

There are tons of way to intercept key messages. You don't even need any library for this. Using pure Win32 API is OK but if you want simplicity, try handling the ThreadPreprocessMessage event of ComponentDispatcher:

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,...),这就是您想要的.

The event is able to receive any key messages before it is actually sent to your window. So it's what you want in this case if you want to handle raw messages (instead of handling PreviewKeyDown, ...).

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

The AddHook method allows to add some hook proc for the window but it's really limited in WPF (while the equivalent WndProc protected method of Form in winforms can intercept much more messages).

这篇关于在WPF窗口中接收带有窗口消息的键盘事件(HwndSource.AddHook)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆