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 / chap24 / polyline / iconnpt.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  9KB  |  399 lines

  1. /*
  2.  * ICONNPT.CPP
  3.  * Polyline Component Chapter 23
  4.  *
  5.  * Implementation of CImpIConnectionPoint for the Polyline object
  6.  * as well as CConnectionPoint.
  7.  *
  8.  *
  9.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Microsoft
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include "polyline.h"
  18.  
  19.  
  20. /*
  21.  * CImpIConnPtCont:CImpIConnPtCont
  22.  * CImpIConnPtCont::~CImpIConnPtCont
  23.  *
  24.  * Constructor Parameters:
  25.  *  pObj            PCPolyline pointing to the object we live in.
  26.  *  pUnkOuter       LPUNKNOWN of the controlling unknown.
  27.  */
  28.  
  29. CImpIConnPtCont::CImpIConnPtCont(PCPolyline pObj
  30.     , LPUNKNOWN pUnkOuter)
  31.     {
  32.     m_cRef=0;
  33.     m_pObj=pObj;
  34.     m_pUnkOuter=pUnkOuter;
  35.     return;
  36.     }
  37.  
  38.  
  39. CImpIConnPtCont::~CImpIConnPtCont(void)
  40.     {
  41.     return;
  42.     }
  43.  
  44.  
  45.  
  46.  
  47. /*
  48.  * CImpIConnPtCont::QueryInterface
  49.  * CImpIConnPtCont::AddRef
  50.  * CImpIConnPtCont::Release
  51.  */
  52.  
  53. STDMETHODIMP CImpIConnPtCont::QueryInterface(REFIID riid, PPVOID ppv)
  54.     {
  55.     return m_pUnkOuter->QueryInterface(riid, ppv);
  56.     }
  57.  
  58. STDMETHODIMP_(ULONG) CImpIConnPtCont::AddRef(void)
  59.     {
  60.     ++m_cRef;
  61.     return m_pUnkOuter->AddRef();
  62.     }
  63.  
  64. STDMETHODIMP_(ULONG) CImpIConnPtCont::Release(void)
  65.     {
  66.     --m_cRef;
  67.     return m_pUnkOuter->Release();
  68.     }
  69.  
  70.  
  71.  
  72.  
  73.  
  74. /*
  75.  * CImpIConnPtCont::EnumConnectionPoints
  76.  *
  77.  * Purpose:
  78.  *  Not implemented.
  79.  *
  80.  * Return Value:
  81.  *  HRESULT         E_NOTIMPL
  82.  */
  83.  
  84. STDMETHODIMP CImpIConnPtCont::EnumConnectionPoints
  85.     (LPENUMCONNECTIONPOINTS *ppEnum)
  86.     {
  87.     *ppEnum=NULL;
  88.     return ResultFromScode(E_NOTIMPL);
  89.     }
  90.  
  91.  
  92.  
  93. /*
  94.  * CImpIConnPtCont::FindConnectionPoint
  95.  *
  96.  * Purpose:
  97.  *  Returns a pointer to the IConnectionPoint for a given
  98.  *  outgoing IID.
  99.  *
  100.  * Parameters:
  101.  *  riid            REFIID of the outgoing interface for which
  102.  *                  a connection point is desired.
  103.  *  ppCP            IConnectionPoint ** in which to return
  104.  *                  the pointer after calling AddRef.
  105.  *
  106.  * Return Value:
  107.  *  HRESULT         NOERROR if the connection point is found,
  108.  *                  E_NOINTERFACE if it's not supported.
  109.  */
  110.  
  111. STDMETHODIMP CImpIConnPtCont::FindConnectionPoint(REFIID riid
  112.     , IConnectionPoint **ppCP)
  113.     {
  114.     *ppCP=NULL;
  115.  
  116.     //CHAPTER24MOD
  117.     if (IID_IPolylineAdviseSink10==riid
  118.         || DIID_DIPolylineAdviseSink10==riid)
  119.         {
  120.         /*
  121.          * This tells the connection point which one we're
  122.          * using.  Note that Polyline only has one
  123.          * connection point and can handle only one sink.
  124.          */
  125.         m_pObj->m_pConnPt->SetIID(riid);
  126.  
  127.         return m_pObj->m_pConnPt->QueryInterface
  128.             (IID_IConnectionPoint, (PPVOID)ppCP);
  129.         }
  130.     //End CHAPTER24MOD
  131.  
  132.     return ResultFromScode(E_NOINTERFACE);
  133.     }
  134.  
  135.  
  136.  
  137.  
  138.  
  139. //CConnectionPoint implementation
  140.  
  141. /*
  142.  * CConnectionPoint::CConnectionPoint
  143.  * CConnectionPoint::~CConnectionPoint
  144.  *
  145.  * Parameters (Constructor):
  146.  *  pObj            PCPolyline of the object we're in.  We can
  147.  *                  query this for the IConnectionPointContainer
  148.  *                  interface we might need.
  149.  */
  150.  
  151. CConnectionPoint::CConnectionPoint(PCPolyline pObj)
  152.     {
  153.     m_cRef=0;
  154.  
  155.     /*
  156.      * Our lifetime is controlled by the connectable object itself,
  157.      * although other external clients will call AddRef and Release.
  158.      * Since we're nested in the connectable object's lifetime,
  159.      * there's no need to call AddRef on pObj.
  160.      */
  161.     m_pObj=pObj;
  162.     return;
  163.     }
  164.  
  165. CConnectionPoint::~CConnectionPoint(void)
  166.     {
  167.     ReleaseInterface(m_pObj->m_pAdv);
  168.     return;
  169.     }
  170.  
  171.  
  172.  
  173. //CHAPTER24MOD
  174.  
  175. /*
  176.  * CConnectionPoint::SetIID
  177.  *
  178.  * Purpose:
  179.  *  Informs the connection point which outgoing interface
  180.  *  it should use (vtable or dispatch interface).
  181.  *
  182.  * Parameters:
  183.  *  riid            REFIID of the interface we're using.
  184.  */
  185.  
  186. void CConnectionPoint::SetIID(REFIID riid)
  187.     {
  188.     m_iid=riid;
  189.     return;
  190.     }
  191.  
  192. //End CHAPTER24MOD
  193.  
  194.  
  195.  
  196.  
  197. /*
  198.  * CConnectionPoint::QueryInterface
  199.  * CConnectionPoint::AddRef
  200.  * CConnectionPoint::Release
  201.  *
  202.  * Purpose:
  203.  *  Non-delegating IUnknown members for CConnectionPoint.
  204.  */
  205.  
  206. STDMETHODIMP CConnectionPoint::QueryInterface(REFIID riid
  207.     , LPVOID *ppv)
  208.     {
  209.     *ppv=NULL;
  210.  
  211.     if (IID_IUnknown==riid || IID_IConnectionPoint==riid)
  212.         *ppv=(LPVOID)this;
  213.  
  214.     if (NULL!=*ppv)
  215.         {
  216.         ((LPUNKNOWN)*ppv)->AddRef();
  217.         return NOERROR;
  218.         }
  219.  
  220.     return ResultFromScode(E_NOINTERFACE);
  221.     }
  222.  
  223. STDMETHODIMP_(ULONG) CConnectionPoint::AddRef(void)
  224.     {
  225.     return ++m_cRef;
  226.     }
  227.  
  228. STDMETHODIMP_(ULONG) CConnectionPoint::Release(void)
  229.     {
  230.     if (0!=--m_cRef)
  231.         return m_cRef;
  232.  
  233.     delete this;
  234.     return 0;
  235.     }
  236.  
  237.  
  238.  
  239. /*
  240.  * CConnectionPoint::GetConnectionInterface
  241.  *
  242.  * Purpose:
  243.  *  Returns the IID of the outgoing interface supported through
  244.  *  this connection point.
  245.  *
  246.  * Parameters:
  247.  *  pIID            IID * in which to store the IID.
  248.  */
  249.  
  250. STDMETHODIMP CConnectionPoint::GetConnectionInterface(IID *pIID)
  251.     {
  252.     if (NULL==pIID)
  253.         return ResultFromScode(E_POINTER);
  254.  
  255.     //CHPATER24MOD
  256.     *pIID=m_iid;
  257.     //End CHAPTER24MOD
  258.     return NOERROR;
  259.     }
  260.  
  261.  
  262.  
  263. /*
  264.  * CConnectionPoint::GetConnectionPointContainer
  265.  *
  266.  * Purpose:
  267.  *  Returns a pointer to the IConnectionPointContainer that
  268.  *  is manageing this connection point.
  269.  *
  270.  * Parameters:
  271.  *  ppCPC           IConnectionPointContainer ** in which to return
  272.  *                  the pointer after calling AddRef.
  273.  */
  274.  
  275. STDMETHODIMP CConnectionPoint::GetConnectionPointContainer
  276.     (IConnectionPointContainer **ppCPC)
  277.     {
  278.     return m_pObj->QueryInterface(IID_IConnectionPointContainer
  279.         , (void **)ppCPC);
  280.     }
  281.  
  282.  
  283.  
  284. /*
  285.  * CConnectionPoint::Advise
  286.  *
  287.  * Purpose:
  288.  *  Provides this connection point with a notification sink to
  289.  *  call whenever the appropriate outgoing function/event occurs.
  290.  *
  291.  * Parameters:
  292.  *  pUnkSink        LPUNKNOWN to the sink to notify.  The connection
  293.  *                  point must QueryInterface on this pointer to obtain
  294.  *                  the proper interface to call.  The connection
  295.  *                  point must also insure that any pointer held has
  296.  *                  a reference count (QueryInterface will do it).
  297.  *  pdwCookie       DWORD * in which to store the connection key for
  298.  *                  later calls to Unadvise.
  299.  */
  300.  
  301. STDMETHODIMP CConnectionPoint::Advise(LPUNKNOWN pUnkSink
  302.     , DWORD *pdwCookie)
  303.     {
  304.     IPolylineAdviseSink10  *pSink;
  305.  
  306.     *pdwCookie=0;
  307.  
  308.     //Only allow one connection
  309.     if (NULL!=m_pObj->m_pAdv)
  310.         return ResultFromScode(CONNECT_E_ADVISELIMIT);
  311.  
  312.     //CHAPTER24MOD
  313.     /*
  314.      * Polyline code is set to handle calls to
  315.      * IPolylineAdviseSink10 everywhere else around the code.
  316.      * To handle calling a control container's dispinterface
  317.      * implementation of the dispatch version of this interface,
  318.      * we'll create an instance of our own CAdviseRouter
  319.      * and get an IPolylineAdviseSink10 from it.  That router
  320.      * will then convert vtable calls into IDispatch calls.
  321.      */
  322.     if (DIID_DIPolylineAdviseSink10==m_iid)
  323.         {
  324.         IDispatch  *pIDisp;
  325.  
  326.         if (FAILED(pUnkSink->QueryInterface(m_iid
  327.             , (PPVOID)&pIDisp)))
  328.             {
  329.             return ResultFromScode(CONNECT_E_CANNOTCONNECT);
  330.             }
  331.  
  332.         /*
  333.          * We have IDispatch, create a wrapper for it,
  334.          * which takes ownership of the pointer.
  335.          */
  336.         pSink=new CAdviseRouter(pIDisp, m_pObj);
  337.         pSink->AddRef();
  338.         }
  339.  
  340.     //Otherwise, do what we always did before
  341.     if (IID_IPolylineAdviseSink10==m_iid)
  342.         {
  343.         //Check for the right interface on the sink.
  344.         if (FAILED(pUnkSink->QueryInterface(m_iid
  345.             , (PPVOID)&pSink)))
  346.             {
  347.             return ResultFromScode(CONNECT_E_CANNOTCONNECT);
  348.             }
  349.         }
  350.     //End CHAPTER24MOD
  351.  
  352.  
  353.     *pdwCookie=ADVISEKEY;
  354.     m_pObj->m_pAdv=pSink;
  355.     return NOERROR;
  356.     }
  357.  
  358.  
  359.  
  360. /*
  361.  * CConnectionPoint::Unadvise
  362.  *
  363.  * Purpose:
  364.  *  Terminates the connection to the notification sink identified
  365.  *  with dwCookie (that was returned from Advise).  The connection
  366.  *  point has to Release any held pointers for that sink.
  367.  *
  368.  * Parameters:
  369.  *  dwCookie        DWORD connection key from Advise.
  370.  */
  371.  
  372. STDMETHODIMP CConnectionPoint::Unadvise(DWORD dwCookie)
  373.     {
  374.     if (0==dwCookie)
  375.         return ResultFromScode(E_INVALIDARG);
  376.  
  377.     if (ADVISEKEY!=dwCookie)
  378.         ResultFromScode(CONNECT_E_NOCONNECTION);
  379.  
  380.     ReleaseInterface(m_pObj->m_pAdv);
  381.     return NOERROR;
  382.     }
  383.  
  384.  
  385.  
  386. /*
  387.  * CConnectionPoint::EnumConnections
  388.  *
  389.  * Purpose:
  390.  *  Not implemented.
  391.  */
  392.  
  393. STDMETHODIMP CConnectionPoint::EnumConnections
  394.     (LPENUMCONNECTIONS *ppEnum)
  395.     {
  396.     *ppEnum=NULL;
  397.     return ResultFromScode(E_NOTIMPL);
  398.     }
  399.