0

我有一个带有文本框的窗口。光标位于文本框内。如果我按下一个键,那么我会在 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 事件?

4

2 回答 2

4

有很多方法可以拦截关键消息。你甚至不需要任何图书馆。使用纯 Win32 API 是可以的,但如果您想要简单,请尝试处理以下ThreadPreprocessMessage事件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, ...),这就是您在这种情况下想要的。

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

于 2015-10-13T14:33:03.607 回答
0

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

PM> Install-Package ManagedWinapi

有关键盘和其他消息拦截的广泛示例:http: //mwinapi.sourceforge.net/

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

这两个库都有很好的文档记录。

于 2015-10-13T13:23:27.890 回答