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