如何在 MFC No CLR 中访问 Winform ActiveX 控件

Posted

技术标签:

【中文标题】如何在 MFC No CLR 中访问 Winform ActiveX 控件【英文标题】:How to Access Winform ActiveX Control in MFC No CLR 【发布时间】:2014-11-04 23:08:22 【问题描述】:

我的项目由四个项目组成

    通过互操作公开 COM 接口的 C# DLL 一个 WPF 控件,其中包含 1 中公开类的实例 使用 ElementHost 承载 WPF 控件 2 的 Winform ActiveX 使用来自 3 的控件的 MFC 对话框应用程序

Winform ActiveX (3) 通过 2 中的函数从 1 公开类实例。我希望通过 ActiveX 从 MFC 对话框应用程序访问该类实例。我环顾四周,发现您可以使用 CWinFormControl 做到这一点。但是我不能使用 /clr 重新编译 MFC 应用程序。因此我不能使用 CWinFormControl。

我可以通过 COM 从 MFC 应用程序访问 1 中的类并运行所有函数等,但是该类是不同的实例,因为 DLL 是在其自己的空间中加载的。

ActiveX 运行良好,可以很好地显示所有 WPF 数据。

所以问题是如何在不使用 CWinFormControl 的情况下从 MFC 应用程序中获取指向 ActiveX 控件的指针?

我尝试从 ActiveX 导入 TLB 并尝试在类向导中为其创建“变量”,但它报告 TLB 不可用。我也尝试通过手动创建变量直接创建 DDX 条目,但 DDX 不允许指针。

有什么想法吗?

【问题讨论】:

【参考方案1】:

问题基本上是尝试在 MFC 中访问 Winform ActiveX 控件,而无需使用 clr 或托管 C++。

对于任何对此问题的答案感兴趣的人来说,我是如何解决它的。首先,您必须动态创建 ActiveX 并将其放置在您自己的位置。

在您的 MFC 对话框标题中添加一个 CWnd

   CWnd m_MyActiveX;

在您的 MFC Cpp 中动态创建控件

   m_MyActiveX.CreateControl("MyActiveX.ProgId","",WS_VISIBLE,prect,this,5000);

注意:您可以在 Winform ActiveX 属性中找到 progid

[ProgId("MyActiveX.ProgId")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]  

接下来为您需要的 COM 对象获取 IUnknown 和 QueryInterface

IOleObjectPtr pOleObj(m_MyActiveX.GetControlUnknown ());
if (pOleObj != NULL) 

    MyCOMObject::IWpfHostPtr host;
    pOleObj.QueryInterface(__uuidof(MyCOMObject::IWpfHostPtr),&host);

    MyCOMWPFControl::IWpfControl wpf;
    host->GetWpfControl ( &wpf );

    MyInternalCOMObject::ICoolObject internal;
    wpf->GetInternalObject ( &internal );

    internal->AndAPartridgeInaPearTree ();
 

注意:实际的 Winform ActiveX 必须派生自某个已知接口

public partial class WpfHost : UserControl, IWpfHost 

使用此技术,您可以成功地将 WPF 控件托管在旧版 MFC 应用程序上,并通过 COM 与它们进行通信,而无需使用托管 C++

【讨论】:

以上是关于如何在 MFC No CLR 中访问 Winform ActiveX 控件的主要内容,如果未能解决你的问题,请参考以下文章

MFC 和 /clr C++ 项目中的库

使用 /clr 编译 MFC 应用程序(步骤 1:链接到动态 DLL)

ATL CLR MFC Win32 常规 的区别

VC学习笔记---ATL MFC CLR三个库的区别

运行使用 /clr 构建的 DLL 的本机 C++ 应用程序时访问冲突

在 MFC 的 SC_CLOSE 中选择“NO”时如何返回应用程序