我们开始在我们的系统中使用 MATLAB 64 位,并且我们的一些旧 M 代码使用自定义版本的MSFlexGrid ActiveX 组件,因此我们决定编写一个 .Net 64 位版本。
ActiveX 通过 Windows 窗体主机公开。
[ProgId("FlexiGrid")]
[Guid("88888888-4444-4444-4444-CCCCCCCCCCCC")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public partial class GridWinFormsHost : UserControl
{
}
Windows 窗体用户控件通过 ElementHost 嵌入 WPF 用户控件。
private IGrid grid;
private void GridWinFormsHostLoad(object sender, System.EventArgs e)
{
var host = new ElementHost { Dock = DockStyle.Fill };
this.grid = new GridView();
host.Child = (GridView)this.grid;
this.Controls.Add(host);
}
该控件已成功注册,对 MATLAB 可见,并且可以通过以下方式实例化
actxcontrol('FlexiGrid', Position, Fig, CallBack);
GridWinForms 中公开的方法和属性是可见的,并且可以获取/设置/调用。
然而,在实例化 ActiveX 之后,我们最终需要通过 MEX DLL 在 MATLAB 进程中调用 .Net。调用在 .Net 中成功执行,但当控制从 .Net 返回时,MATLAB 进程冻结。在不实例化 ActiveX 控件的情况下运行相同的代码成功并且 MATLAB 不会冻结,这意味着实例化 .Net ActiveX 控件可能是 MATLAB 冻结的原因。
在搜索解决方案时,我遇到了这个 MSDN 线程,其中指出:“出现此问题是因为 Windows 窗体使用的消息循环和 COM 客户端应用程序提供的消息循环不同。” 原始海报得出结论,他用 WPF + MFC 解决了这个问题,但没有详细说明解决方案。
我还发现这篇 MSDN 文章指出:“要使 Windows 窗体在 COM 客户端应用程序中正常工作,您必须在 Windows 窗体消息循环上运行该窗体。” 这也很有希望,除了解决方案专注于创建新的 Windows 窗体窗口,但我需要运行嵌入在 MATLAB 窗口中的 Windows 窗体用户控件。
所以这个问题似乎与在非托管应用程序上托管托管 ActiveX 控件有关 - 有什么想法吗?