| Tenouk C & C++ | MFC Home | OLE & Containers 3 | OLE & Containers 5 | Download | Site Index |


 

 

 

 

 

OLE Embedded Components and Containers Part 4

 

 

 

 

 

 

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.

  1. The EX32B From Scratch...continue

 

 

Add the #include directive in ex32bView.cpp.

 

#include <afxole.h>

 

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

 

Listing 7.

 

Modify the constructor as shown below.

 

CEx28bView::CEx28bView(): m_sizeTotal(20000, 25000),

    // 20 x 25 cm when printed

      m_rectTracker(0, 0, 0, 0)

{

      m_cfObjDesc = ::RegisterClipboardFormat(CF_OBJECTDESCRIPTOR);

      m_cfEmbedded = ::RegisterClipboardFormat(CF_EMBEDDEDOBJECT);

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

--------------------------------------------------------------------------------------------------------------------------------------

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

 

Listing 8.

 

Modify the OnDraw() as shown below.

 

void CEx32bView::OnDraw(CDC* pDC)

{

      CEx32bDoc* pDoc = GetDocument();

 

      if(pDoc->m_lpOleObj != NULL)

      {

            VERIFY(::OleDraw(pDoc->m_lpOleObj, DVASPECT_CONTENT, pDC->GetSafeHdc(), m_rectTracker) == S_OK);

      }

 

      m_tracker.m_rect = m_rectTracker;

      pDC->LPtoDP(m_tracker.m_rect);   // device

      if(pDoc->m_bHatch)

      {

            m_tracker.m_nStyle |= CRectTracker::hatchInside;

      }

      else

      {

            m_tracker.m_nStyle &= ~CRectTracker::hatchInside;

      }

      m_tracker.Draw(pDC);

}

 

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

 

Listing 9.

 

Edit OnPreparePrinting() as shown below.

 

BOOL CEx32bView::OnPreparePrinting(CPrintInfo* pInfo)

{

      pInfo->SetMaxPage(1);

      return DoPreparePrinting(pInfo);

}

 

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

 

Listing 10.

 

Edit OnInitialUpdate() as shown below.

 

void CEx32bView::OnInitialUpdate()

{

      TRACE("CEx32bView::OnInitialUpdate\n");

      m_rectTracker = CRect(1000, -1000, 5000, -5000);

      m_tracker.m_nStyle = CRectTracker::solidLine | CRectTracker::resizeOutside;

      SetScrollSizes(MM_HIMETRIC, m_sizeTotal);

      CScrollView::OnInitialUpdate();

}

 

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

 

Listing 11.

 

Edit other message handlers as shown in the following codes.

 

void CEx32bView::OnEditCopy()

{

      // TODO: Add your command handler code here

      COleDataSource* pSource = SaveObject();

      if(pSource)

    {

      pSource->SetClipboard(); // OLE deletes data source

    }

}

 

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

 

Listing 12.

 

void CEx32bView::OnUpdateEditCopy(CCmdUI* pCmdUI)

{

      // TODO: Add your command update UI handler code here

      // serves Copy, Cut, and Copy To

    pCmdUI->Enable(GetDocument()->m_lpOleObj != NULL);

}

 

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

 

Listing 13.

 

void CEx32bView::OnEditCopyto()

{

    // TODO: Add your command handler code here

    // Copy text to an .STG file (nothing special about STG ext)

    CFileDialog dlg(FALSE, "stg", "*.stg");

    if (dlg.DoModal() != IDOK) {

        return;

    }

      CEx32bDoc* pDoc = GetDocument();

      // Create a structured storage home for the object (m_pStgSub).

      // Create a root storage file, then a sub storage named "sub."

      LPSTORAGE pStgRoot;

      VERIFY(::StgCreateDocfile(dlg.GetPathName().AllocSysString(),

               STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, 0, &pStgRoot) == S_OK);

      ASSERT(pStgRoot != NULL);

      LPSTORAGE pStgSub;

      VERIFY(pStgRoot->CreateStorage(CEx32bDoc::s_szSub, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE,0, 0, &pStgSub) == S_OK);

      ASSERT(pStgSub != NULL);

      // Get the IPersistStorage* for the object

      LPPERSISTSTORAGE pPS = NULL;

      VERIFY(pDoc->m_lpOleObj->QueryInterface(IID_IPersistStorage, (void**) &pPS) == S_OK);

      // Finally, save the object in its new home in the user's file

      VERIFY(::OleSave(pPS, pStgSub, FALSE) == S_OK);

      // FALSE means different stg

      pPS->SaveCompleted(NULL);  // What does this do?

      pPS->Release();

      pStgSub->Release();

      pStgRoot->Release();

}

 

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

 

Listing 14.

 

void CEx32bView::OnEditCut()

{

    // TODO: Add your command handler code here

    OnEditCopy();

    GetDocument()->OnEditClearAll();

}

 

 

Listing 15.

 

void CEx32bView::OnEditInsertobject()

{

      // TODO: Add your command handler code here

      CEx32bDoc* pDoc = GetDocument();

      COleInsertDialog dlg;

      if(dlg.DoModal() == IDCANCEL) return;

      // no addrefs done for GetInterface

      LPOLECLIENTSITE pClientSite = (LPOLECLIENTSITE)pDoc->GetInterface(&IID_IOleClientSite);

      ASSERT(pClientSite != NULL);

      pDoc->DeleteContents();

      VERIFY(::OleCreate(dlg.GetClassID(), IID_IOleObject, OLERENDER_DRAW, NULL, pClientSite, pDoc->m_pTempStgSub,(void**) &pDoc->m_lpOleObj) == S_OK);

      SetViewAdvise();

 

      pDoc->m_lpOleObj->DoVerb(OLEIVERB_SHOW, NULL, pClientSite, 0, NULL, NULL); // OleRun doesn't show it

      SetNames();

      GetDocument()->SetModifiedFlag();

      GetSize();

      pDoc->UpdateAllViews(NULL);

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

 

Listing 16.

 

void CEx32bView::OnUpdateEditInsertobject(CCmdUI* pCmdUI)

{

      // TODO: Add your command update UI handler code here

      pCmdUI->Enable(GetDocument()->m_lpOleObj == NULL);

}

 

void CEx32bView::OnEditPaste()

{

      // TODO: Add your command handler code here

      CEx32bDoc* pDoc = GetDocument();

      COleDataObject dataObject;

      VERIFY(dataObject.AttachClipboard());

      pDoc->DeleteContents();

      DoPasteObjectDescriptor(&dataObject);

      DoPasteObject(&dataObject);

      SetViewAdvise();

      GetSize();

      pDoc->SetModifiedFlag();

      pDoc->UpdateAllViews(NULL);

}

 

void CEx32bView::OnUpdateEditPaste(CCmdUI* pCmdUI)

{

      // TODO: Add your command update UI handler code here

      // Make sure that object data is available

      COleDataObject dataObject;

      if (dataObject.AttachClipboard() && dataObject.IsDataAvailable(m_cfEmbedded))

       { pCmdUI->Enable(TRUE); }

    else

    { pCmdUI->Enable(FALSE); }

}

 

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

 

Listing 17.

 

void CEx32bView::OnEditPastefrom()

{

    // TODO: Add your command handler code here

    CEx32bDoc* pDoc = GetDocument();

    // Paste from an .STG file

    CFileDialog dlg(TRUE, "stg", "*.stg");

    if (dlg.DoModal() != IDOK)

    { return; }

    // Open the storage and sub storage

      LPSTORAGE pStgRoot;

      VERIFY(::StgOpenStorage(dlg.GetPathName().AllocSysString(), NULL,

               STGM_READ|STGM_SHARE_EXCLUSIVE, NULL, 0, &pStgRoot) == S_OK);

      ASSERT(pStgRoot != NULL);

 

      LPSTORAGE pStgSub;

      VERIFY(pStgRoot->OpenStorage(CEx32bDoc::s_szSub, NULL,

               STGM_READ|STGM_SHARE_EXCLUSIVE, NULL, 0, &pStgSub) == S_OK);

      ASSERT(pStgSub != NULL);

 

      // Copy the object data from the user storage to the temporary storage

      VERIFY(pStgSub->CopyTo(NULL, NULL, NULL, pDoc->m_pTempStgSub) == S_OK);

      // Finally, load the object -- pClientSite not necessary

      LPOLECLIENTSITE pClientSite =

            (LPOLECLIENTSITE) pDoc->GetInterface(&IID_IOleClientSite);

      ASSERT(pClientSite != NULL);

      pDoc->DeleteContents();

      VERIFY(::OleLoad(pDoc->m_pTempStgSub, IID_IOleObject, pClientSite,  (void**) &pDoc->m_lpOleObj) == S_OK);

      SetViewAdvise();

      pStgSub->Release();

      pStgRoot->Release();

      GetSize();

    pDoc->SetModifiedFlag();

    pDoc->UpdateAllViews(NULL);

}

 

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

 

Listing 18.

 

void CEx32bView::OnLButtonDblClk(UINT nFlags, CPoint point)

{

    // TODO: Add your message handler code here and/or call default

    if(m_tracker.HitTest(point) == CRectTracker::hitNothing) return;

    // Activate the object

    CEx32bDoc* pDoc = GetDocument();

    if(pDoc->m_lpOleObj != NULL)

    {

      LPOLECLIENTSITE pClientSite = (LPOLECLIENTSITE) pDoc->GetInterface(&IID_IOleClientSite);

      ASSERT(pClientSite != NULL);

      VERIFY(pDoc->m_lpOleObj->DoVerb(OLEIVERB_OPEN, NULL, pClientSite, 0, GetSafeHwnd(), CRect(0, 0, 0, 0)) == S_OK);

      SetNames();

      GetDocument()->SetModifiedFlag();

    }

}

 

void CEx32bView::OnLButtonDown(UINT nFlags, CPoint point)

{

      // TODO: Add your message handler code here and/or call default

      TRACE("**Entering CEx32bView::OnLButtonDown -- point = (%d, %d)\n", point.x, point.y);

       if(m_tracker.Track(this, point, FALSE, NULL))

       {

            CClientDC dc(this);

            OnPrepareDC(&dc);

            m_rectTracker = m_tracker.m_rect;

            dc.DPtoLP(m_rectTracker); // Update logical coords

            GetDocument()->UpdateAllViews(NULL);

      }

      TRACE("**Leaving CEx32bView::OnLButtonDown\n");

}

 

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

 

Listing 19.

 

BOOL CEx32bView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)

{

      // TODO: Add your message handler code here and/or call default

      if(m_tracker.SetCursor(pWnd, nHitTest))

      {

            return TRUE;

      }

      else

      {

            return CScrollView::OnSetCursor(pWnd, nHitTest, message);

      }

}

 

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

 

Listing 20.

 

Complete other message handlers’ codes previously added.

 

void CEx32bView::GetSize()

{

      CEx32bDoc* pDoc = GetDocument();

      if(pDoc->m_lpOleObj != NULL)

      {

            SIZEL size;   // Ask the component for its size

            pDoc->m_lpOleObj->GetExtent(DVASPECT_CONTENT, &size);

            m_rectTracker.right = m_rectTracker.left + size.cx;

            m_rectTracker.bottom = m_rectTracker.top - size.cy;

      }

}

 

void CEx32bView::SetNames()

{

      CEx32bDoc* pDoc = GetDocument();

      CString strApp = AfxGetApp()->m_pszAppName;

      if(pDoc->m_lpOleObj != NULL)

      { pDoc->m_lpOleObj->SetHostNames(strApp.AllocSysString(), NULL); }

}

 

void CEx32bView::SetViewAdvise()

{

      CEx32bDoc* pDoc = GetDocument();

      if(pDoc->m_lpOleObj != NULL)

      {

            LPVIEWOBJECT2 pViewObj;

            pDoc->m_lpOleObj->QueryInterface(IID_IViewObject2, (void**) &pViewObj);

            LPADVISESINK pAdviseSink =  (LPADVISESINK) pDoc->GetInterface(&IID_IAdviseSink);

            VERIFY(pViewObj->SetAdvise(DVASPECT_CONTENT, 0, pAdviseSink) == S_OK);

            pViewObj->Release();

      }

}

 

 

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

 

Listing 21.

 

BOOL CEx32bView::MakeMetafilePict(COleDataSource *pSource)

{

      CEx32bDoc* pDoc = GetDocument();

      COleDataObject dataObject;

      LPDATAOBJECT pDataObj; // OLE object's IDataObject interface

      VERIFY(pDoc->m_lpOleObj->QueryInterface(IID_IDataObject, (void**) &pDataObj) == S_OK);

      dataObject.Attach(pDataObj);

    FORMATETC fmtem;

    SETFORMATETC(fmtem, CF_METAFILEPICT, DVASPECT_CONTENT, NULL, TYMED_MFPICT, -1);

    if (!dataObject.IsDataAvailable(CF_METAFILEPICT, &fmtem))

    {

      TRACE("CF_METAFILEPICT format is unavailable\n");

      return FALSE;

    }

      // Just copy the metafile handle from the OLE object

      //  to the clipboard data object

      STGMEDIUM stgmm;

      VERIFY(dataObject.GetData(CF_METAFILEPICT, &stgmm, &fmtem));

      pSource->CacheData(CF_METAFILEPICT, &stgmm, &fmtem);

      return TRUE;

}

 

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

 

Listing 22.

 

 

COleDataSource* CEx32bView::SaveObject()

{

      TRACE("Entering CEx32bView::SaveObject\n");

      CEx32bDoc* pDoc = GetDocument();

       if (pDoc->m_lpOleObj != NULL)

       {

        COleDataSource* pSource = new COleDataSource();

        // CODE FOR OBJECT DATA

        FORMATETC fmte;

        SETFORMATETC(fmte, m_cfEmbedded, DVASPECT_CONTENT, NULL, TYMED_ISTORAGE, -1);

        STGMEDIUM stgm;

        stgm.tymed = TYMED_ISTORAGE;

        stgm.pstg = pDoc->m_pTempStgSub;

        stgm.pUnkForRelease = NULL;

            pDoc->m_pTempStgSub->AddRef();   // must do both!

            pDoc->m_pTempStgRoot->AddRef();

            pSource->CacheData(m_cfEmbedded, &stgm, &fmte);

            // metafile needed too

            MakeMetafilePict(pSource);

            // CODE FOR OBJECT DESCRIPTION DATA

            HGLOBAL hObjDesc = ::GlobalAlloc(GMEM_SHARE, sizeof(OBJECTDESCRIPTOR));

            LPOBJECTDESCRIPTOR pObjDesc = (LPOBJECTDESCRIPTOR) ::GlobalLock(hObjDesc);

            pObjDesc->cbSize = sizeof(OBJECTDESCRIPTOR);

            pObjDesc->clsid = CLSID_NULL;

            pObjDesc->dwDrawAspect = 0;

            pObjDesc->dwStatus = 0;

            pObjDesc->dwFullUserTypeName = 0;

            pObjDesc->dwSrcOfCopy = 0;

            pObjDesc->sizel.cx = 0;

            pObjDesc->sizel.cy = 0;

            pObjDesc->pointl.x = 0;

            pObjDesc->pointl.y = 0;

            ::GlobalUnlock(hObjDesc);

            pSource->CacheGlobalData(m_cfObjDesc, hObjDesc);

            return pSource;

      }

      return NULL;

}

 

 

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

 

Listing 23.

 

BOOL CEx32bView::DoPasteObject(COleDataObject *pDataObject)

{

    TRACE("Entering CEx32bView::DoPasteObject\n");

    // Update command UI should keep us out of here if not CF_EMBEDDEDOBJECT

    if (!pDataObject->IsDataAvailable(m_cfEmbedded))

    {

      TRACE("CF_EMBEDDEDOBJECT format is unavailable\n");

      return FALSE;

    }

      CEx32bDoc* pDoc = GetDocument();

      // Now create the object from the IDataObject*.

      //  OleCreateFromData will use CF_EMBEDDEDOBJECT format if available.

      LPOLECLIENTSITE pClientSite = (LPOLECLIENTSITE) pDoc->GetInterface(&IID_IOleClientSite);

      ASSERT(pClientSite != NULL);

      VERIFY(::OleCreateFromData(pDataObject->m_lpDataObject, IID_IOleObject,OLERENDER_DRAW, NULL, pClientSite,

               pDoc->m_pTempStgSub, (void**) &pDoc->m_lpOleObj) == S_OK);

      return TRUE;

}

 

 

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

 

Listing 24.

 

BOOL CEx32bView::DoPasteObjectDescriptor(COleDataObject *pDataObject)

{

      TRACE("Entering CEx32bView::DoPasteObjectDescriptor\n");

      STGMEDIUM stg;

      FORMATETC fmt;

      CEx32bDoc* pDoc = GetDocument();

    if (!pDataObject->IsDataAvailable(m_cfObjDesc))

    {

      TRACE("OBJECTDESCRIPTOR format is unavailable\n");

      return FALSE;

    }

      SETFORMATETC(fmt, m_cfObjDesc, DVASPECT_CONTENT, NULL, TYMED_HGLOBAL, -1);

      VERIFY(pDataObject->GetData(m_cfObjDesc, &stg, &fmt));

 

      return TRUE;

}

 

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

 

Listing 25.

 

Add the following prototype in ex32bDoc.h.

 

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

 

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

 

Listing 26.

 

Manually add the following interface OleClientSite and AdviseSink.

 

              BEGIN_INTERFACE_PART(OleClientSite, IOleClientSite)

            STDMETHOD(SaveObject)();

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

            STDMETHOD(GetContainer)(LPOLECONTAINER*);

            STDMETHOD(ShowObject)();

            STDMETHOD(OnShowWindow)(BOOL);

            STDMETHOD(RequestNewObjectLayout)();

      END_INTERFACE_PART(OleClientSite)

 

      BEGIN_INTERFACE_PART(AdviseSink, IAdviseSink)

            STDMETHOD_(void,OnDataChange)(LPFORMATETC, LPSTGMEDIUM);

            STDMETHOD_(void,OnViewChange)(DWORD, LONG);

            STDMETHOD_(void,OnRename)(LPMONIKER);

            STDMETHOD_(void,OnSave)();

            STDMETHOD_(void,OnClose)();

      END_INTERFACE_PART(AdviseSink)

 

      DECLARE_INTERFACE_MAP()

 

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

 

Listing 27.

 

Add the following friend class (in order to access the private variables and member functions).

 

friend class CEx32bView;

 

private:

      LPOLEOBJECT m_lpOleObj;

      LPSTORAGE m_pTempStgRoot;

      LPSTORAGE m_pTempStgSub;

      BOOL m_bHatch;

      static const OLECHAR* s_szSub;

 

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

 

Listing 28.

 

Add the following constant in ex32bDoc.cpp.

 

const OLECHAR* CEx32bDoc::s_szSub = L"sub"; // static

 

 

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

 

Listing 29.

 

Add the following interface mapping of the OleClientSite and AdviseSink.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BEGIN_INTERFACE_MAP(CEx32bDoc, CDocument)

      INTERFACE_PART(CEx32bDoc, IID_IOleClientSite, OleClientSite)

      INTERFACE_PART(CEx32bDoc, IID_IAdviseSink, AdviseSink)

END_INTERFACE_MAP()

 

 

Listing 30.

 

Then, add the implementation of the OleClientSite.

 

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

// Implementation of IOleClientSite

 

STDMETHODIMP_(ULONG) CEx32bDoc::XOleClientSite::AddRef()

{

      TRACE("CEx32bDoc::XOleClientSite::AddRef\n");

      METHOD_PROLOGUE(CEx32bDoc, OleClientSite)

      return pThis->InternalAddRef();

}

 

STDMETHODIMP_(ULONG) CEx32bDoc::XOleClientSite::Release()

{

      TRACE("CEx32bDoc::XOleClientSite::Release\n");

      METHOD_PROLOGUE(CEx32bDoc, OleClientSite)

      return pThis->InternalRelease();

}

 

STDMETHODIMP CEx32bDoc::XOleClientSite::QueryInterface(REFIID iid, LPVOID* ppvObj)

{

      ITrace(iid, "CEx32bDoc::XOleClientSite::QueryInterface");

      METHOD_PROLOGUE(CEx32bDoc, OleClientSite)

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

}

 

STDMETHODIMP CEx32bDoc::XOleClientSite::SaveObject()

{

      TRACE("CEx32bDoc::XOleClientSite::SaveObject\n");

      METHOD_PROLOGUE(CEx32bDoc, OleClientSite)

      ASSERT_VALID(pThis);

 

      LPPERSISTSTORAGE lpPersistStorage;

      pThis->m_lpOleObj->QueryInterface(IID_IPersistStorage, (void**) &lpPersistStorage);

      ASSERT(lpPersistStorage != NULL);

      HRESULT hr = NOERROR;

      if (lpPersistStorage->IsDirty() == NOERROR)

      {

            // NOERROR == S_OK != S_FALSE, therefore object is dirty!

            hr = ::OleSave(lpPersistStorage, pThis->m_pTempStgSub, TRUE);

            if (hr != NOERROR)

                  hr = lpPersistStorage->SaveCompleted(NULL);

            // Mark the document as dirty, if save successful

            pThis->SetModifiedFlag();

      }

      lpPersistStorage->Release();

      pThis->UpdateAllViews(NULL);

      return hr;

}

 

STDMETHODIMP CEx32bDoc::XOleClientSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)

{

      TRACE("CEx32bDoc::XOleClientSite::GetMoniker\n");

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32bDoc::XOleClientSite::GetContainer(LPOLECONTAINER* ppContainer)

{

      TRACE("CEx32bDoc::XOleClientSite::GetContainer\n");

      return E_NOTIMPL;

}

 

STDMETHODIMP CEx32bDoc::XOleClientSite::ShowObject()

{

      TRACE("CEx32bDoc::XOleClientSite::ShowObject\n");

      METHOD_PROLOGUE(CEx32bDoc, OleClientSite)

      ASSERT_VALID(pThis);

      pThis->UpdateAllViews(NULL);

      return NOERROR;

}

 

STDMETHODIMP CEx32bDoc::XOleClientSite::OnShowWindow(BOOL fShow)

{

      TRACE("CEx32bDoc::XOleClientSite::OnShowWindow\n");

      METHOD_PROLOGUE(CEx32bDoc, OleClientSite)

      ASSERT_VALID(pThis);

      pThis->m_bHatch = fShow;

      pThis->UpdateAllViews(NULL);

      return NOERROR;

}

 

STDMETHODIMP CEx32bDoc::XOleClientSite::RequestNewObjectLayout()

{

      TRACE("CEx32bDoc::XOleClientSite::RequestNewObjectLayout\n");

      return E_NOTIMPL;

}

 

 

And for AdviseSink.

 

 

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

// Implementation of IAdviseSink

STDMETHODIMP_(ULONG) CEx32bDoc::XAdviseSink::AddRef()

{

      TRACE("CEx32bDoc::XAdviseSink::AddRef\n");

      METHOD_PROLOGUE(CEx32bDoc, AdviseSink)

      return pThis->InternalAddRef();

}

 

STDMETHODIMP_(ULONG) CEx32bDoc::XAdviseSink::Release()

{

      TRACE("CEx32bDoc::XAdviseSink::Release\n");

      METHOD_PROLOGUE(CEx32bDoc, AdviseSink)

      return pThis->InternalRelease();

}

 

STDMETHODIMP CEx32bDoc::XAdviseSink::QueryInterface(REFIID iid, LPVOID* ppvObj)

{

      ITrace(iid, "CEx32bDoc::XAdviseSink::QueryInterface");

      METHOD_PROLOGUE(CEx32bDoc, AdviseSink)

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

}

 

STDMETHODIMP_(void) CEx32bDoc::XAdviseSink::OnDataChange(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)

{

      TRACE("CEx32bDoc::XAdviseSink::OnDataChange\n");

      METHOD_PROLOGUE(CEx32bDoc, AdviseSink)

      ASSERT_VALID(pThis);

      // Interesting only for advanced containers.  Forward it such that

      //  containers do not have to implement the entire interface.

}

 

STDMETHODIMP_(void) CEx32bDoc::XAdviseSink::OnViewChange(DWORD aspects, LONG /*lindex*/)

{

      TRACE("CEx32bDoc::XAdviseSink::OnViewChange\n");

      METHOD_PROLOGUE(CEx32bDoc, AdviseSink)

      ASSERT_VALID(pThis);

      pThis->UpdateAllViews(NULL);  // the really important one

}

 

STDMETHODIMP_(void) CEx32bDoc::XAdviseSink::OnRename(LPMONIKER /*lpMoniker*/)

{

      TRACE("CEx32bDoc::XAdviseSink::OnRename\n");

      // Interesting only to the OLE link object. Containers ignore this.

}

 

STDMETHODIMP_(void) CEx32bDoc::XAdviseSink::OnSave()

{

      TRACE("CEx32bDoc::XAdviseSink::OnSave\n");

      METHOD_PROLOGUE(CEx32bDoc, AdviseSink)

      ASSERT_VALID(pThis);

      pThis->UpdateAllViews(NULL);

}

 

STDMETHODIMP_(void) CEx32bDoc::XAdviseSink::OnClose()

{

      TRACE("CEx32bDoc::XAdviseSink::OnClose\n");

      METHOD_PROLOGUE(CEx32bDoc, AdviseSink)

      ASSERT_VALID(pThis);

      pThis->UpdateAllViews(NULL);

}

 

Add/edit other codes.

 

CEx32bDoc::CEx32bDoc()

{

      // TODO: add one-time construction code here

      m_lpOleObj = NULL;

      m_pTempStgRoot = NULL;

      m_pTempStgSub = NULL;

      m_bHatch = FALSE;

}

 

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

 

Listing 31.

 

BOOL CEx32bDoc::OnNewDocument()

{

      TRACE("Entering CEx32bDoc::OnNewDocument\n");

      // Create a structured storage home for the object (m_pTempStgSub).

      //  This is a temporary file -- random name supplied by OLE.

      VERIFY(::StgCreateDocfile(NULL,

            STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE | STGM_DELETEONRELEASE,

            0, &m_pTempStgRoot) == S_OK);

      ASSERT(m_pTempStgRoot != NULL);

 

      VERIFY(m_pTempStgRoot->CreateStorage(OLESTR("sub"),

         STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &m_pTempStgSub) == S_OK);

      ASSERT(m_pTempStgSub != NULL);

      return CDocument::OnNewDocument();

}

 

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

 

Listing 32.

 

void CEx32bDoc::DeleteContents()

{

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

      if(m_lpOleObj != NULL) {

         // If object is running, close it, which releases our IOleClientSite

            m_lpOleObj->Close(OLECLOSE_NOSAVE);

            m_lpOleObj->Release(); // should be final release (or else..)

            m_lpOleObj = NULL;

      }

}

 

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

 

Listing 33.

 

 

void CEx32bDoc::OnCloseDocument()

{

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

      m_pTempStgSub->Release(); // must release BEFORE calling base class

      m_pTempStgRoot->Release();

      CDocument::OnCloseDocument();

}

 

BOOL CEx32bDoc::SaveModified()

{

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

      // Eliminate "save to file" message

      return TRUE;

}

 

void CEx32bDoc::OnEditClearAll()

{

    // TODO: Add your command handler code here

    DeleteContents();

    UpdateAllViews(NULL);

    SetModifiedFlag();

    m_bHatch = FALSE;

}

 

void ITrace(REFIID iid, const char* str)

{

      OLECHAR* lpszIID;

      ::StringFromIID(iid, &lpszIID);

      CString strIID = lpszIID;

      TRACE("%s - %s\n", (const char*) strIID, (const char*) str);

      AfxFreeTaskMem(lpszIID);

}

 

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

 

Listing 34.

 

Add the following #include directives for automation support in StdAfx.h.

 

#include <afxole.h>

#include <afxodlgs.h>

 

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

 

Listing 35.

 

Then add the following in ex32b.cpp at the beginning of the InitInstance().

 

 

AfxOleInit();

 

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

 

Listing 36.

 

 

 

 

 

 

Further reading and digging:

  1. DCOM at MSDN.

  2. COM+ at MSDN.

  3. COM at MSDN.

  4. Win32 process, thread and synchronization story can be found starting from Module R.

  5. MSDN MFC 7.0 class library online documentation.

  6. MSDN MFC 9.0 class library online documentation - latest version.

  7. MSDN Library

  8. Windows data type.

  9. Win32 programming Tutorial.

  10. The best of C/C++, MFC, Windows and other related books.

  11. Unicode and Multibyte character set: Story and program examples.

 

 


 

| Tenouk C & C++ | MFC Home | OLE & Containers 3 | OLE & Containers 5 | Download | Site Index |