【发布时间】:2016-01-11 02:53:28
【问题描述】:
我有一个带有文本框的窗口。光标位于文本框内。如果我按下一个键,那么我会在 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 事件?
【问题讨论】:
-
e.Handled = true根据定义,意味着您已经处理了它,因此 Windows 不会进一步处理它。如果您提供一些关于您最终想要实现的目标的背景信息,将会更有帮助。 -
是的,我知道,但是仍然会收到按键预览事件,你可以测试一下: textBox.PreviewKeyDown += (ss, ee) => { Debug.WriteLine("PreviewKeyDown"); }; textBox.PreviewKeyUp += (ss, ee) => { Debug.WriteLine("PreviewKeyUp"); };但是为什么在 WndProc 中没有收到这些事件呢?
-
AFAIK,Preview* 事件是 WPF 内部的,不会广播,因为它们对外部应用程序没有太大意义 - 包括 Windows 本身。
-
好的,但是是否可以在它处理的文本框之前接收关键事件(使用窗口消息)?
-
你需要创建钩子来拦截所有的消息。 WPF 不会为单个控件公开 hWnd。您应该查看 ManagedWinApi 以创建一个挂钩。如果您当前的代码不起作用,则可能是在处理完消息后正在广播 WndProc。通过使用 win32 api,您需要创建一个更高优先级的钩子,以便在 WPF 窗口本身之前获取消息。
标签: c# wpf wndproc keyboard-hook window-messages