我有一个WPF对话框,我希望在Win32应用程序中显示为非模态窗口。 调用window.Show()正确显示窗口,并且所有鼠标事件都由它正确处理,但所有键盘事件都由父Win32窗口处理,因此即使用户将焦点放在文本框中,任何键入的文本也会显示在父Win32窗口中!
这似乎是WinForms / WPF互操作中的一个已知问题,在这种情况下通过在显示对话框之前调用ElementHost.EnableModelessKeyboardInterop
来修复。这会导致将新的消息过滤器添加到WinForms消息循环中,以便可以拦截键盘事件并将其适当地路由到WPF对话框。
不幸的是我的主机应用程序不是WinForms应用程序,所以我没有选择调用EnableModelessKeyboardInterop
。有没有办法在Win32应用程序中做类似的事情?
答案 0 :(得分:1)
您可以转发键盘消息,但您需要自己完成这项工作。
基本思路如下:
创建并显示WPF窗口后,获取其HwndSource
:
HwndSource source = HwndSource.FromVisual(wnd) as HwndSource;
在您的消息循环中,每当您收到键盘消息时,请将HwndSource
强制转换为IKeyboardInputSink
,然后调用相应的方法。
基本上,如果您获得WM_KEYDOWN
,则应致电TranslateAccelerator()
,或者如果您获得WM_CHAR
,则应致电TranslateChar()
。 IKeyboardInputSink
的文档不是很好,但它确实指定了哪些方法处理哪些消息。如果已处理消息,该方法将返回true
,因此您将知道是否需要在Win32端处理消息。