home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap19 / hcosmo / iadvsink.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-22  |  4.5 KB  |  175 lines

  1. /*
  2.  * IADVSINK.CPP
  3.  * Cosmo Handler Chapter 19
  4.  *
  5.  * Implementation of the IAdviseSink interface for the Cosmo Handler
  6.  * such that it is notified when data is modified in the server.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "hcosmo.h"
  17.  
  18.  
  19. /*
  20.  * CImpIAdviseSink::CImpIAdviseSink
  21.  * CImpIAdviseSink::~CImpIAdviseSink
  22.  *
  23.  * Parameters (Constructor):
  24.  *  pObj            PCFigure of the object we're in.
  25.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  26.  */
  27.  
  28. CImpIAdviseSink::CImpIAdviseSink(PCFigure pObj
  29.     , LPUNKNOWN pUnkOuter)
  30.     {
  31.     m_cRef=0;
  32.     m_pObj=pObj;
  33.     m_pUnkOuter=pUnkOuter;
  34.     return;
  35.     }
  36.  
  37. CImpIAdviseSink::~CImpIAdviseSink(void)
  38.     {
  39.     return;
  40.     }
  41.  
  42.  
  43.  
  44.  
  45. /*
  46.  * CImpIAdviseSink::QueryInterface
  47.  * CImpIAdviseSink::AddRef
  48.  * CImpIAdviseSink::Release
  49.  */
  50.  
  51. STDMETHODIMP CImpIAdviseSink::QueryInterface(REFIID riid, PPVOID ppv)
  52.     {
  53.     /*
  54.      * Conceptually, and from the view of the container and the
  55.      * local server, the IAdviseSink interface is implemented
  56.      * on a different object than the rest of the handler's
  57.      * interfaces.  For that reason, this QueryInterface only
  58.      * exposes IUnknown and IAdviseSink.  That makes it appear
  59.      * as a separate object although it doesn't have to be an
  60.      * explicitly separate object inside this handler (no one
  61.      * outside the handler cares about our implementation).  Note
  62.      * that reference counting still affects the entire object.
  63.      */
  64.     if (IID_IUnknown==riid || IID_IAdviseSink==riid)
  65.         {
  66.         *ppv=this;
  67.         AddRef();
  68.         return NOERROR;
  69.         }
  70.  
  71.     return ResultFromScode(E_NOINTERFACE);
  72.     }
  73.  
  74.  
  75. STDMETHODIMP_(ULONG) CImpIAdviseSink::AddRef(void)
  76.     {
  77.     return ++m_cRef;
  78.     }
  79.  
  80. STDMETHODIMP_(ULONG) CImpIAdviseSink::Release(void)
  81.     {
  82.     return --m_cRef;
  83.     }
  84.  
  85.  
  86.  
  87.  
  88. /*
  89.  * CImpIAdviseSink::OnViewChange
  90.  *
  91.  * Purpose:
  92.  *  We don't do anything here because we generate OnViewChange for
  93.  *  the container inside OnDataChange.  The problem is that
  94.  *  OnViewChange will come before OnDataChange, so if we called the
  95.  *  container's OnViewChange here it would turn around and call our
  96.  *  IViewObject::Draw which would draw with outdated data. Therefore
  97.  *  we ignore this notification and wait for OnDataChange, since
  98.  *  that implies a view change as well.  Then we can retrieve the
  99.  *  new data first, then send OnViewChange to the container such
  100.  *  that we'll repaint with the new data.
  101.  */
  102.  
  103. STDMETHODIMP_(void) CImpIAdviseSink::OnViewChange(DWORD dwAspect
  104.     , LONG lindex)
  105.     {
  106.     return;
  107.     }
  108.  
  109.  
  110.  
  111. /*
  112.  * CImpIAdviseSink::OnDataChange
  113.  *
  114.  * Purpose:
  115.  *  Tells us that things changed in the server.  We asked for data
  116.  *  on the advise so we can copy it from here into our own structure
  117.  *  such that on the next OnViewChange we can repaint with it.
  118.  */
  119.  
  120. STDMETHODIMP_(void) CImpIAdviseSink::OnDataChange(LPFORMATETC pFE
  121.     , LPSTGMEDIUM pSTM)
  122.     {
  123.     //Get the new data first, then notify the container to repaint.
  124.     if ((pFE->cfFormat==m_pObj->m_cf)
  125.         && (TYMED_HGLOBAL & pSTM->tymed))
  126.         {
  127.         PPOLYLINEDATA      ppl;
  128.  
  129.         ppl=(PPOLYLINEDATA)GlobalLock(pSTM->hGlobal);
  130.         memcpy(&m_pObj->m_pl, ppl, CBPOLYLINEDATA);
  131.         GlobalUnlock(pSTM->hGlobal);
  132.  
  133.         /*
  134.          * Now tell the container that the view changed, but only
  135.          * if the view is not frozen.'
  136.          */
  137.         if (pFE->dwAspect & m_pObj->m_dwAdviseAspects
  138.             && !(pFE->dwAspect & m_pObj->m_dwFrozenAspects))
  139.             {
  140.             //Pass this on to the container.
  141.             if (NULL!=m_pObj->m_pIAdvSinkView)
  142.                 {
  143.                 m_pObj->m_pIAdvSinkView->OnViewChange(pFE->dwAspect
  144.                     , pFE->lindex);
  145.                 }
  146.             }
  147.         }
  148.  
  149.     return;
  150.     }
  151.  
  152.  
  153.  
  154. /*
  155.  * All others are uninteresting because if the container wants these
  156.  * it will have called IOleObject::Advise which we passed on through
  157.  * to the default handler.  IViewObject::SetAdvise is the only one
  158.  * we override.
  159.  */
  160.  
  161. STDMETHODIMP_(void) CImpIAdviseSink::OnRename(LPMONIKER pmk)
  162.     {
  163.     return;
  164.     }
  165.  
  166. STDMETHODIMP_(void) CImpIAdviseSink::OnSave(void)
  167.     {
  168.     return;
  169.     }
  170.  
  171. STDMETHODIMP_(void) CImpIAdviseSink::OnClose(void)
  172.     {
  173.     return;
  174.     }
  175.