1
votes

My Project Consists of Four Items

  1. C# DLL Which Exposes a COM Interface via Interop
  2. A WPF Control which contains an Instance of an exposed class in 1
  3. A Winform ActiveX which hosts the WPF control in 2 using ElementHost
  4. An MFC Dialog Application using the Control from 3

The Winform ActiveX (3) exposes the class instance from 1 via a function in 2. I wish to access this class instance from the MFC dialog application through the ActiveX. I have looked around and found you can do this using CWinFormControl. However I am not at liberty to recompile the MFC app using /clr. Therefore I cannot use CWinFormControl.

I can access the class in 1 via COM from the MFC app and run all the functions etc however the class is a different instance as the DLL is loaded in its own space.

The ActiveX works well and displays all the WPF data nicely.

So the question is how do I get a pointer to the ActiveX control from within the MFC app without using CWinFormControl?

I have tried importing the TLB from the ActiveX and attempting to create a "Variable" for it in the Class wizard but it reports that the TLB is unavailable. I have also tried directly creating a DDX entry by manually creating a variable but DDX doesn't allow pointers.

Any ideas?

1

1 Answers

3
votes

The Question is basically trying to access a Winform ActiveX Control in MFC without having to use clr or managed C++.

For anyone interested in the answer to this question here is how I solved it. First off you have to dynamically create the ActiveX and place it your self.

In Your MFC Dialog header add a CWnd

   CWnd m_MyActiveX;

In your MFC Cpp dynamically create the Control

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

NOTE: you can find the progid in your Winform ActiveX attributes

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

Next Grab the IUnknown and QueryInterface for the COM Object You need

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 ();
 }

NOTE: The Actual Winform ActiveX must derive from some known Interface

public partial class WpfHost : UserControl, IWpfHost 

Using this Technique you successfully host WPF Controls on your Legacy MFC Applications and communicate with them via COM without resorting to Managed C++