我有一个 WinForms 表单,它曾经是一个独立的应用程序,但现在作为更大的 WPF 应用程序的一部分启动。它仍然是一个单独的窗口,不包含在 WPF 窗口中。我看到的问题是窗口中的 ProcessCmdKey 事件不再触发,因此我在处理特殊命令键时遇到问题。这曾经工作得很好,并且快捷方式处理代码与之前相比没有变化。
问题的根源似乎是表单不再从 WinForms Application.Run 方法初始化,因此它不再有自己的消息循环。有没有办法解决这个问题,同时仍然让 WPF 和 WinForms 窗口共享 UI 线程,或者我是否必须为 WinForms 窗口设置一个单独的线程才能工作?如果可能的话,我想避免它,因为我必须为现在通过简单方法调用完成的所有事情设置跨线程通信。
您的猜测是准确的,ProcessCmdKey()是直接从 Winforms 消息循环中调用的,由 开始Application.Run()。您现在正在运行 WPF 消息循环,它不知道有关 Winforms 键盘处理的任何信息。选项卡也应该无法正常工作。
对此没有明确的解决方案,对象模型差异太大。 System.Windows.Forms.Integration提供两者之间的互操作,但在控制级别而不是窗口级别工作。Form.ShowDialog()是一个可能的解决方法。
是的,您可以启动一个新的 STA 线程(使用Thread.SetApartmentState)并调用Application.Run()以启动 Winforms 消息循环。然而,一个令人讨厌的问题是这些窗体与 WPF 窗口没有 Z 顺序关系。它们很容易消失在另一个应用程序的窗口后面。修复这个问题需要 pinvoking SetParent(),该Owner属性将抛出异常。