65.9K
CodeProject is changing. Read more.
Home

A COM class (DLL) for embedding an embeddable OLE object

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.45/5 (7 votes)

Aug 24, 2005

1 min read

viewsIcon

59941

downloadIcon

1416

A COM class (DLL) that embeds an embeddable OLE object.

Introduction

Using MFC, we can easily develop an ActiveX container application, but unfortunately, it only works with the doc/view architecture as an executing file. If you want to embed an OLE embeddable object but your program is not an executable program and it has to be a DLL (for example, for many kinds of plug-ins, they work as DLL files), then this article will give you help.

Using the code

It's very simple to use. This COM object has only three methods, Create, Open, and OnSize.

  1. You must declare the interface, and add the include files where it works (note: this COM object will work as a child window).

    In the tester, I added it to CTesterDlg as an element.

    #include "..\emboleobjctrl\emboleobjctrl_i.h"
    
    IEmbOleObjControl * m_pCtrl;
  2. Initialize the object's pointer to NULL:
    CtesterDlg::CtesterDlg(CWnd* pParent /*=NULL*/)
        :CDialog(CtesterDlg::IDD, pParent)
    
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
        m_pCtrl = NULL;
    }
  3. Create the instance, and create the window:
    void CtesterDlg::ObBnClickedCreate()
    {
      if(m_pCtrl)   //if the object exists then quit
         return;
      HRESULT hr = ::CoCreateInstance(CLSID_EmbOleObjControl, 
                   NULL,CLSCTX_ALL,IID_IEmbOleObjControl, 
                   (void **)&m_pCtrl);
      if(SUCCEEDED(hr))
      {
          HWND hWnd;
          GetDlgItem(IDC_STATICOWNER,&hWnd);
          m_pCtrl->Create(hWnd);
          //create needs a parameter as the control's container window,
      }
    }
  4. Open the specific file and the specific OLE server:
    void CtesterDlg::OnBnClickedBtnopen()
    {
        if(!m_pCtrl)
        {
            AfxMessageBox("please create the control first");
            return;
        }
        CString strInfo;
        CWnd *pWnd = GetDlgItem(IDC_EDTPATH);
        pWnd->GetWindowText(strInfo);
        _bstr_t bstrInfo(strInfo.GetBuffer());
        static CLSID const clsid_App ={ 0x7b93e267, 0x6bbc, 0x11d4, 
               { 0xa5, 0x4d, 0x0, 0x50, 0xba, 0xdb, 0x14, 0xa3 } };
        m_pCtrl->Open(clsid_App,bstrInfo);
           //clsid_app : the ole server's clsid
           //bstrInfo: the file's path
    }
  5. When the container window's size changes, call IFoxitPDFControl::OnSize() (for the current case, the container is not sizeable).
  6. Before the container window is destroyed, destroy (release) it.
    void CtesterDlg::OnCancel()
    {
         if(m_pCtrl)
            m_pCtrl->Release();
         CDialog::OnCancel();
    }

Points of interest

Wrapping the doc/view architecture into a DLL module is not easy since the mainframe window in that architecture works as an overlapped window, it doesn't work as a child window; but here it must work as a child window (strictly, it works as a popup window here). In order to adjust the window's position, there is an additional method exported (OnMove). Even now, there is a problem annoying me, that this COM object can't work with MS-Word correctly. Hope somebody here can correct it to work with any OLE server without problems.