Win32应用程序中托管的非模态WPF对话框不会收到键盘事件

时间:2017-06-15 17:44:54

标签: .net wpf winapi modeless-dialog

我有一个WPF对话框,我希望在Win32应用程序中显示为非模态窗口。 调用window.Show()正确显示窗口,并且所有鼠标事件都由它正确处理,但所有键盘事件都由父Win32窗口处理,因此即使用户将焦点放在文本框中,任何键入的文本也会显示在父Win32窗口中!

这似乎是WinForms / WPF互操作中的一个已知问题,在这种情况下通过在显示对话框之前调用ElementHost.EnableModelessKeyboardInterop来修复。这会导致将新的消息过滤器添加到WinForms消息循环中,以便可以拦截键盘事件并将其适当地路由到WPF对话框。

不幸的是我的主机应用程序不是WinForms应用程序,所以我没有选择调用EnableModelessKeyboardInterop。有没有办法在Win32应用程序中做类似的事情?

1 个答案:

答案 0 :(得分:1)

您可以转发键盘消息,但您需要自己完成这项工作。

基本思路如下:

  1. 创建并显示WPF窗口后,获取其HwndSource

    HwndSource source = HwndSource.FromVisual(wnd) as HwndSource;

  2. 在您的消息循环中,每当您收到键盘消息时,请将HwndSource强制转换为IKeyboardInputSink,然后调用相应的方法。

  3. 基本上,如果您获得WM_KEYDOWN,则应致电TranslateAccelerator(),或者如果您获得WM_CHAR,则应致电TranslateChar()IKeyboardInputSink的文档不是很好,但它确实指定了哪些方法处理哪些消息。如果已处理消息,该方法将返回true,因此您将知道是否需要在Win32端处理消息。