Win32 应用中托管的非模式 WPF 对话框不接收键盘事件



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

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

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

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

基本思路如下:

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

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

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

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

最新更新