2

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

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

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

4

1 回答 1

1

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

基本思路如下:

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

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

  2. 在您的消息循环中,每当您收到键盘消息时,将其HwndSource转换为IKeyboardInputSink并调用适当的方法。

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

于 2017-06-16T16:52:02.500 回答