Unmanaged MFC/ActiveX calls WPF controls
Using WPF as usercontrol ------> WPF. dll
public partial class WPFUserControl : UserControl{ public WPFUserControl() { InitializeComponent(); }}
Winform usercontrol contains WPF. dll made into COM components ----------> WF. dll and WF. TLB
1) Check winform project properties --> Application --> assembly information --> make assembly com-visible.
2) Check the project properties --> build --> Register for com InterOP.
3) reference the reference used by the WPF project. The focus is to reference the windowsformsintergeration library.
4) reference the project WPF
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch),ComVisibleAttribute(true)]public interface IWfUserCtrl{ [DispId(1)] bool setWindow(int width,int height);}[ComVisible(true), ClassInterface(ClassInterfaceType.None), ProgId("IWfUserCtrl.1")]public partial class WfContrastAgentGridCtrl : UserControl, IWfUserCtrl{ private WPFUserControl m_wpfUserCtrl; public WfContrastAgentGridCtrl() { InitializeComponent(); //Add WPF control inside Winform ElementHost elementHost = new ElementHost(); m_wpfUserCtrl= new WPFUserControl (); elementHost.Child = m_wpfUserCtrl; elementHost.Dock = DockStyle.Fill; this.Controls.Add(elementHost); } public bool setWindow(int width,int height) { return true; }}
Use MFC to call the COM component TLB and run the COM component DLL
1)regasm.exe com. dll
2) # import "com. TLB" no_namespace
3) used in oninitdialog () of the DLG class
#define ID_VIEW_GRIDCTRL 111const CString cstrlProgID(_T("IWfUserCtrl.1"));class Dlg{ private: IWfUserCtrl * m_pUserCtrl; CWnd * m_WfWnd; protected: virtual BOOL OnInitDialog();;}BOOL Dlg::OnInitDialog() { BOOL locStat = FALSE; m_WfWnd= new CWnd(); if (m_WfWnd== NULL) { cout<<"Create m_WfWnd failed"<<endl; } locStat = m_WfContrastAgentWnd->CreateControl(cstrlProgID,_T("IWfUserCtrl"), WS_CHILD | WS_VISIBLE, CRect(10,10,400,800),this,ID_VIEW_GRIDCTRL); if (!locStat) { cout<<"locStat is false"<<endl; } else { cout<<"locStat is true"<<endl; } LPUNKNOWN pUnknown = m_WfContrastAgentWnd->GetControlUnknown(); LPVOID pCSInterface = NULL; HRESULT hr = pUnknown->QueryInterface(__uuidof(IWfContrastAgentGridCtrl),(void **)&pCSInterface); if (hr != S_OK) { cout<<"HRESULT hr is failed!"<<endl; } else { cout<<"hr == S_OK"<<endl; m_pUserCtrl= (IWfUserCtrl*)pCSInterface; }}
For details, see the code