| Tenouk | Home | Previous | Next | Download  |  Site Index  |  Disclaimer  |  Privacy | Contact | Tell friends |


 

 

OLE Embedded Components and Containers part 8

 

Program examples compiled using Visual C++ 6.0 compiler on Windows XP Pro machine with Service Pack 2. The Excel version is Excel 2003/Office 11. Topics and sub topics for this tutorial are listed below. Don’t forget to read Tenouk’s small disclaimer. The supplementary notes for this tutorial are IOleObject and OLE.

 

Index:
 
The Coding Part

 

 

 

The Coding Part

 

Add the following code to ex32c.h.

 

friend class CEx32cDoc;

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 1.

 

Add the following code to the InitInstance() of ex32c.cpp.

 

TRACE("CEx32cApp::InitInstance\n");

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 2.

 

Edit the following code portion.

 

      // When a server application is launched stand-alone, it is a good idea

      //  to update the system registry in case it has been damaged.

      m_server.UpdateRegistry(OAT_SERVER);

      AfxMessageBox("Server can't be run stand-alone, use container -- Registry updated");

      return FALSE;

 

//    // Dispatch commands specified on the command line

//    if (!ProcessShellCommand(cmdInfo))

//          return FALSE;

 

//    // The one and only window has been initialized, so show and update it.

//    m_pMainWnd->ShowWindow(SW_SHOW);

//    m_pMainWnd->UpdateWindow();

 

//    return TRUE;

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 3.

 

And the following code to the ExitInstance().

 

int CEx32cApp::ExitInstance()

{

      // TODO: Add your specialized code here and/or call the base class

      TRACE("CEx32cApp::ExitInstance\n");

      return CWinApp::ExitInstance();

}

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 4.

 

Edit the OnDraw() code of ex32cView.cpp.

 

void CEx32cView::OnDraw(CDC* pDC)

{

      CEx32cDoc* pDoc = GetDocument();

      ASSERT_VALID(pDoc);

      pDC->Rectangle(CRect(500, -1000, 1500, -2000));

      pDC->TextOut(5, 5, pDoc->m_strText);

}

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 5.

 

Edit the OnPrepareDC() as shown below.

 

void CEx32cView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)

{

      // TODO: Add your specialized code here and/or call the base class

      pDC->SetMapMode(MM_HIMETRIC);

}

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 6.

 

Add the following codes to ex32cDoc.h just after the preprocessor directives

 

extern const CLSID clsid; // defined in ex32c.cpp

void ITrace(REFIID iid, const char* str);

 

#define SETFORMATETC(fe, cf, asp, td, med, li) \

      ((fe).cfFormat=cf, \

       (fe).dwAspect=asp, \

       (fe).ptd=td, \

       (fe).tymed=med, \

       (fe).lindex=li)

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 7.

 

Add the following friend class, then adds those member variables and member function.

 

friend class CEx32cView;

 

private:

      CString m_strText;

      LPOLECLIENTSITE m_lpClientSite;

      LPOLEADVISEHOLDER m_lpOleAdviseHolder;

      LPDATAADVISEHOLDER m_lpDataAdviseHolder;

      CString m_strContainerApp;

      CString m_strContainerObj;

 

      HGLOBAL MakeMetaFile();

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 8.

 

Manually add the following interface for IOleObject, IDataObject and IPersistStorage just after the previous codes.

 

BEGIN_INTERFACE_PART(OleObject, IOleObject)

            STDMETHOD(SetClientSite)(LPOLECLIENTSITE);

            STDMETHOD(GetClientSite)(LPOLECLIENTSITE*);

            STDMETHOD(SetHostNames)(LPCOLESTR, LPCOLESTR);

            STDMETHOD(Close)(DWORD);

            STDMETHOD(SetMoniker)(DWORD, LPMONIKER);

            STDMETHOD(GetMoniker)(DWORD, DWORD, LPMONIKER*);

            STDMETHOD(InitFromData)(LPDATAOBJECT, BOOL, DWORD);

            STDMETHOD(GetClipboardData)(DWORD, LPDATAOBJECT*);

            STDMETHOD(DoVerb)(LONG, LPMSG, LPOLECLIENTSITE, LONG,

                  HWND, LPCRECT);

            STDMETHOD(EnumVerbs)(LPENUMOLEVERB*);

            STDMETHOD(Update)();

            STDMETHOD(IsUpToDate)();

            STDMETHOD(GetUserClassID)(LPCLSID);

            STDMETHOD(GetUserType)(DWORD, LPOLESTR*);

            STDMETHOD(SetExtent)(DWORD, LPSIZEL);

            STDMETHOD(GetExtent)(DWORD, LPSIZEL);

            STDMETHOD(Advise)(LPADVISESINK, LPDWORD);

            STDMETHOD(Unadvise)(DWORD);

            STDMETHOD(EnumAdvise)(LPENUMSTATDATA*);

            STDMETHOD(GetMiscStatus)(DWORD, LPDWORD);

            STDMETHOD(SetColorScheme)(LPLOGPALETTE);

      END_INTERFACE_PART(OleObject)

 

      BEGIN_INTERFACE_PART(DataObject, IDataObject)

            STDMETHOD(GetData)(LPFORMATETC, LPSTGMEDIUM);

            STDMETHOD(GetDataHere)(LPFORMATETC, LPSTGMEDIUM);

            STDMETHOD(QueryGetData)(LPFORMATETC);

            STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC, LPFORMATETC);

            STDMETHOD(SetData)(LPFORMATETC, LPSTGMEDIUM, BOOL);

            STDMETHOD(EnumFormatEtc)(DWORD, LPENUMFORMATETC*);

            STDMETHOD(DAdvise)(LPFORMATETC, DWORD, LPADVISESINK, LPDWORD);

            STDMETHOD(DUnadvise)(DWORD);

            STDMETHOD(EnumDAdvise)(LPENUMSTATDATA*);

      END_INTERFACE_PART(DataObject)

 

      BEGIN_INTERFACE_PART(PersistStorage, IPersistStorage)

            STDMETHOD(GetClassID)(LPCLSID);

            STDMETHOD(IsDirty)();

            STDMETHOD(InitNew)(LPSTORAGE);

            STDMETHOD(Load)(LPSTORAGE);

            STDMETHOD(Save)(LPSTORAGE, BOOL);

            STDMETHOD(SaveCompleted)(LPSTORAGE);

            STDMETHOD(HandsOffStorage)();

      END_INTERFACE_PART(PersistStorage)

 

      DECLARE_INTERFACE_MAP()

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

 

Listing 9.

 

Delete (or comment out) the AppWizard generated DECLARE_DISPATCH_MAP and DECLARE_INTERFACE_MAP.

 

 

//    // Generated OLE dispatch map functions

//    //{{AFX_DISPATCH(CEx32cDoc)

//          // NOTE - the ClassWizard will add and remove member functions here.

//          //    DO NOT EDIT what you see in these blocks of generated code !

//    //}}AFX_DISPATCH

//    DECLARE_DISPATCH_MAP()

//    DECLARE_INTERFACE_MAP()

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 10.

 

Add the following #include directive to ex32cDoc.cpp.

 

#include "TextDialog.h"

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 11.

 

Manually add the following interface.

 

BEGIN_INTERFACE_MAP(CEx32cDoc, CDocument)

      INTERFACE_PART(CEx32cDoc, IID_IOleObject, OleObject)

      INTERFACE_PART(CEx32cDoc, IID_IDataObject, DataObject)

      INTERFACE_PART(CEx32cDoc, IID_IPersistStorage, PersistStorage)

END_INTERFACE_MAP()

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 12.

 

Delete (or comment out) the auto AppWizard generated DISPATCH_MAP and INTERFACE_MAP.

 

// BEGIN_DISPATCH_MAP(CEx32cDoc, CDocument)

//    //{{AFX_DISPATCH_MAP(CEx32cDoc)

//          // NOTE - the ClassWizard will add and remove mapping macros here.

//          //      DO NOT EDIT what you see in these blocks of generated code!

//    //}}AFX_DISPATCH_MAP

// END_DISPATCH_MAP()

 

// // Note: we add support for IID_IEx32c to support typesafe binding

// //  from VBA.  This IID must match the GUID that is attached to the

// //  dispinterface in the .ODL file.

 

// // {100A83A5-C1FB-4EA7-8AFC-689433F842E8}

// static const IID IID_IEx32c =

// { 0x100a83a5, 0xc1fb, 0x4ea7, { 0x8a, 0xfc, 0x68, 0x94, 0x33, 0xf8, 0x42, 0xe8 } };

 

// BEGIN_INTERFACE_MAP(CEx32cDoc, CDocument)

//    INTERFACE_PART(CEx32cDoc, IID_IEx32c, Dispatch)

// END_INTERFACE_MAP()

 

 

OLE Embedded Components and Containers - MFC C++ code snippet

 

Listing 13.

 

Add the implementation for the interfaces. Firstly add the implementation for OleObject just after the previous commented codes.

 

///////////////////////////////////////////////////////////////////////

// CEx32cDoc OLE interface functions

STDMETHODIMP_(ULONG) CEx32cDoc::XOleObject::AddRef()

{

      TRACE("CEx32cDoc::XOleObject::AddRef\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      return pThis->InternalAddRef();

}

 

STDMETHODIMP_(ULONG) CEx32cDoc::XOleObject::Release()

{

      TRACE("CEx32cDoc::XOleObject::Release\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      return pThis->InternalRelease();

}

 

STDMETHODIMP CEx32cDoc::XOleObject::QueryInterface(

      REFIID iid, LPVOID* ppvObj)

{

      ITrace(iid, "CEx32cDoc::XOleObject::QueryInterface");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      return pThis->InternalQueryInterface(&iid, ppvObj);

}

 

STDMETHODIMP CEx32cDoc::XOleObject::SetClientSite(

      LPOLECLIENTSITE pClientSite)

{

      TRACE("CEx32cDoc::XOleObject::SetClientSite\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      // linked objects do not support SetClientSite

      if (pClientSite != NULL)

            pClientSite->AddRef();

      if(pThis->m_lpClientSite != NULL) pThis->m_lpClientSite->Release();

      pThis->m_lpClientSite = pClientSite;

 

      return NOERROR;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::GetClientSite(

      LPOLECLIENTSITE* ppClientSite)

{

      TRACE("CEx32cDoc::XOleObject::GetClientSite\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

 

      *ppClientSite = pThis->m_lpClientSite;

        if (pThis->m_lpClientSite != NULL)

                pThis->m_lpClientSite->AddRef();  // IMPORTANT

      return NOERROR;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::SetHostNames(

      LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)

{

      TRACE("CEx32cDoc::XOleObject::SetHostNames\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

     

      CString strTitle = "EX28C object embedded in ";

      if(szContainerApp != NULL) {

            strTitle += CString(szContainerApp);

      }

      CWnd* pWnd = AfxGetMainWnd();

      pWnd->SetWindowText(strTitle);

     

      return NOERROR;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::Close(DWORD /*dwSaveOption*/)

{

      TRACE("CEx32cDoc::XOleObject::Close\n");

      // linked objects do not support close

 

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::SetMoniker(

      DWORD /*dwWhichMoniker*/, LPMONIKER /*pmk*/)

{

      TRACE("CEx32cDoc::XOleObject::SetMoniker\n");

      // linked objects do not support SetMoniker

 

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::GetMoniker(

      DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)

{

      TRACE("CEx32cDoc::XOleObject::GetMoniker\n");

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::InitFromData(

      LPDATAOBJECT /*pDataObject*/, BOOL /*fCreation*/, DWORD /*dwReserved*/)

{

      TRACE("CEx32cDoc::XOleObject::InitFromData\n");

      // linked objects do not support InitFromData

 

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::GetClipboardData(

      DWORD /*dwReserved*/, LPDATAOBJECT* ppDataObject)

{

      TRACE("CEx32cDoc::XOleObject::GetClipboardData\n");

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::DoVerb(

      LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex,

      HWND hwndParent, LPCRECT lpPosRect)

{                                                          

      TRACE("CEx32cDoc::XOleObject::DoVerb - %d\n", iVerb);

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

 

      pThis->InternalAddRef();    // protect this object

      CWnd* pWnd = AfxGetMainWnd();

      switch (iVerb)

      {

      // open - maps to OnOpen

      case OLEIVERB_OPEN:

      case -OLEIVERB_OPEN-1:  // allows positive OLEIVERB_OPEN-1 in registry

      case OLEIVERB_PRIMARY:  // OLEIVERB_PRIMARY is 0 and "Edit" in registry

      case OLEIVERB_SHOW:

            pWnd->ShowWindow(SW_SHOW);

            pWnd->SetActiveWindow();

            pWnd->SetForegroundWindow();

            break;

 

      // hide maps to OnHide

      case OLEIVERB_HIDE:

      case -OLEIVERB_HIDE-1:  // allows positive OLEIVERB_HIDE-1 in registry

            return E_NOTIMPL;

           

      default:

            // negative verbs not understood should return E_NOTIMPL

            if (iVerb < 0)

                  return E_NOTIMPL;

 

            AfxThrowOleException(OLEOBJ_S_INVALIDVERB);

      }

      pThis->InternalRelease();   // may 'delete this'

      pThis->m_lpClientSite->OnShowWindow(TRUE); // hatch

 

      return NOERROR;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::EnumVerbs(

      IEnumOLEVERB** ppenumOleVerb)

{

      TRACE("CEx32cDoc::XOleObject::EnumVerbs\n");

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::Update()

{

      TRACE("CEx32cDoc::XOleObject::Update\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::IsUpToDate()

{

      TRACE("CEx32cDoc::XOleObject::IsUpToDate\n");

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::GetUserClassID(CLSID* pClsid)

{

      TRACE("CEx32cDoc::XOleObject::GetUserClassID\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

 

      return pThis->m_xPersistStorage.GetClassID(pClsid);

}

 

STDMETHODIMP CEx32cDoc::XOleObject::GetUserType(

      DWORD dwFormOfType, LPOLESTR* ppszUserType)

{

      TRACE("CEx32cDoc::XOleObject::GetUserType\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

 

      *ppszUserType = NULL;

 

      CLSID clsid;

      pThis->m_xOleObject.GetUserClassID(&clsid);

      return OleRegGetUserType(clsid, dwFormOfType, ppszUserType);

}

 

STDMETHODIMP CEx32cDoc::XOleObject::SetExtent(

      DWORD /*dwDrawAspect*/, LPSIZEL /*lpsizel*/)

{

      TRACE("CEx32cDoc::XOleObject::SetExtent\n");

      return E_FAIL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::GetExtent(

      DWORD dwDrawAspect, LPSIZEL lpsizel)

{

      TRACE("CEx32cDoc::XOleObject::GetExtent\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

      // handler returns extent in metafilepict

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::Advise(

      IAdviseSink* pAdvSink, DWORD* pdwConnection)

{

      TRACE("CEx32cDoc::XOleObject::Advise\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

      *pdwConnection = 0;

      if (pThis->m_lpOleAdviseHolder == NULL &&

            ::CreateOleAdviseHolder(&pThis->m_lpOleAdviseHolder)

            != NOERROR) {

            return E_OUTOFMEMORY;

      }

      ASSERT(pThis->m_lpOleAdviseHolder != NULL);

      return pThis->m_lpOleAdviseHolder->Advise(pAdvSink, pdwConnection);

}

 

STDMETHODIMP CEx32cDoc::XOleObject::Unadvise(DWORD dwConnection)

{

      TRACE("CEx32cDoc::XOleObject::Unadvise\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::EnumAdvise(

      LPENUMSTATDATA* ppenumAdvise)

{

      TRACE("CEx32cDoc::XOleObject::EnumAdvise\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32cDoc::XOleObject::GetMiscStatus(

      DWORD dwAspect, DWORD* pdwStatus)

{

      TRACE("CEx32cDoc::XOleObject::GetMiscStatus\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

 

      *pdwStatus = 0;

 

      CLSID clsid;

      pThis->m_xOleObject.GetUserClassID(&clsid);

      return OleRegGetMiscStatus(clsid, dwAspect, pdwStatus);

}

 

STDMETHODIMP CEx32cDoc::XOleObject::SetColorScheme(LPLOGPALETTE lpLogpal)

{

      TRACE("CEx32cDoc::XOleObject::SetColorScheme\n");

      METHOD_PROLOGUE(CEx32cDoc, OleObject)

      ASSERT_VALID(pThis);

 

      return E_NOTIMPL;

}

 

Next, add the implementation codes for DataObject.

 

// CEx32cDoc::XDataObject

// delegate many calls to embedded COleDataSource object, which manages formats

STDMETHODIMP_(ULONG) CEx32cDoc::XDataObject::AddRef()

{

      TRACE("CEx32cDoc::XDataObject::AddRef\n");

      METHOD_PROLOGUE(CEx32cDoc, DataObject)

      return pThis->InternalAddRef();

}

 

STDMETHODIMP_(ULONG) CEx32cDoc::XDataObject::Release()

{

      TRACE("CEx32cDoc::XDataObject::Release\n");

      METHOD_PROLOGUE(CEx32cDoc, DataObject)

      return pThis->InternalRelease();

}

 

STDMETHODIMP CEx32cDoc::XDataObject::QueryInterface(

      REFIID iid, LPVOID* ppvObj)

{

      ITrace(iid, "CEx32cDoc::XDataObject::QueryInterface");

      METHOD_PROLOGUE(CEx32cDoc, DataObject)

      return pThis->InternalQueryInterface(&iid, ppvObj);

}

 

STDMETHODIMP CEx32cDoc::XDataObject::GetData(

      LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)

{

      TRACE("CEx32cDoc::XDataObject::GetData -- %d\n",

              lpFormatEtc->cfFormat);

      METHOD_PROLOGUE(CEx32cDoc, DataObject)

      ASSERT_VALID(pThis);

     

      if(lpFormatEtc->cfFormat != CF_METAFILEPICT) {

            return S_FALSE;

      }

      HGLOBAL hPict = pThis->MakeMetaFile();

      lpStgMedium->tymed = TYMED_MFPICT;

      lpStgMedium->hMetaFilePict = hPict;

      lpStgMedium->pUnkForRelease = NULL;