简体   繁体   English

从WPF应用启动的WinForms窗口中永远不会触发ProcessCmdKey

[英]ProcessCmdKey never fires in WinForms window started from WPF app

I have a WinForms Form that used to be a standalone application, but is now being started as part of a larger WPF app. 我有一个WinForms Form,它曾经是一个独立的应用程序,但是现在正在作为一个更大的WPF应用程序的一部分启动。 It is still a separate window, not contained within a WPF window. 它仍然是一个单独的窗口,未包含在WPF窗口中。 The problem I'm seeing is that the ProcessCmdKey event in the window never fires anymore, so I'm having problems handling special command keys. 我看到的问题是窗口中的ProcessCmdKey事件再也不会触发,因此我在处理特殊命令键时遇到问题。 This used to work fine and the shortcut handling code is unchanged from earlier. 以前可以正常工作,并且快捷方式处理代码与以前的版本相同。

The root of the problem seems to be that the form is no longer being inited from the WinForms Application.Run method, and so it no longer has its own message loop. 问题的根源似乎是不再从WinForms Application.Run方法中初始化该窗体,因此它不再具有自己的消息循环。 Is there any way to fix this while still having the WPF and WinForms windows share an UI thread, or will I have to set up a separate thread for the WinForms window for this to work? 在仍然让WPF和WinForms窗口共享一个UI线程的同时,有什么方法可以解决此问题,或者我是否必须为WinForms窗口设置一个单独的线程才能正常工作? I'd like to avoid it if possible as I then have to set up cross-thread communication for all the things that are now done by simple method calls. 我想避免这种情况,因为那时我必须为现在通过简单方法调用完成的所有事情建立跨线程通信。

Your guess is accurate, ProcessCmdKey() is directly called from the Winforms message loop as started by Application.Run() . 您的猜测是正确的, ProcessCmdKey()是从Application.Run()启动的Winforms消息循环中直接调用的。 You are now running the WPF message loop, it doesn't know anything about the Winforms keyboard handling. 您现在正在运行WPF消息循环,它对Winforms键盘处理一无所知。 Tabbing should be dysfunctional too. 制表也应该功能失调。

There is no clean fix for this, the object models are too different. 尚无明确的解决方案,对象模型差异太大。 System.Windows.Forms.Integration provides interop between the two but that works at the control level, not the window level. System.Windows.Forms.Integration提供了两者之间的互操作,但是在控件级别而不是窗口级别起作用。 Form.ShowDialog() is a possible workaround. Form.ShowDialog()是一种可能的解决方法。

And yes, you can start a new STA thread (use Thread.SetApartmentState ) and call Application.Run() to start a Winforms message loop. 是的,您可以启动一个新的STA线程(使用Thread.SetApartmentState )并调用Application.Run()来启动Winforms消息循环。 A nasty problem with that however is that these forms have no Z-order relationship with the WPF windows. 但是,一个令人讨厌的问题是这些形式与WPF窗口没有Z顺序关系。 They'll easily disappear behind the window of another app. 它们很容易消失在另一个应用程序的窗口后面。 Fixing that requires pinvoking SetParent() , the Owner property will throw an exception. 需要调用SetParent()修复程序, Owner属性将引发异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM