home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / ctlconn.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-16  |  6.5 KB  |  248 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFXCTL_CORE3_SEG
  14. #pragma code_seg(AFXCTL_CORE3_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // Connection map
  26.  
  27. BEGIN_CONNECTION_MAP(COleControl, CCmdTarget)
  28.     CONNECTION_PART(COleControl, IID_IPropertyNotifySink, PropConnPt)
  29. END_CONNECTION_MAP()
  30.  
  31. /////////////////////////////////////////////////////////////////////////////
  32. // COleControl::GetConnectionHook - override the connection map
  33.  
  34. LPCONNECTIONPOINT COleControl::GetConnectionHook(REFIID iid)
  35. {
  36.     if ((m_piidEvents != NULL) && IsEqualIID(iid, *m_piidEvents))
  37.         return (LPCONNECTIONPOINT)((char*)&m_xEventConnPt +
  38.                 offsetof(CConnectionPoint, m_xConnPt));
  39.     else
  40.         return NULL;
  41. }
  42.  
  43. /////////////////////////////////////////////////////////////////////////////
  44. // COleControl::GetExtraConnectionPoints - override the connection map
  45.  
  46. BOOL COleControl::GetExtraConnectionPoints(CPtrArray* pConnPoints)
  47. {
  48.     pConnPoints->Add((char*)&m_xEventConnPt +
  49.         offsetof(CConnectionPoint, m_xConnPt));
  50.     return TRUE;
  51. }
  52.  
  53. /////////////////////////////////////////////////////////////////////////////
  54. // COleControl::XProvideClassInfo
  55.  
  56. STDMETHODIMP_(ULONG) COleControl::XProvideClassInfo::AddRef()
  57. {
  58.     METHOD_PROLOGUE_EX_(COleControl, ProvideClassInfo)
  59.     return (ULONG)pThis->ExternalAddRef();
  60. }
  61.  
  62. STDMETHODIMP_(ULONG) COleControl::XProvideClassInfo::Release()
  63. {
  64.     METHOD_PROLOGUE_EX_(COleControl, ProvideClassInfo)
  65.     return (ULONG)pThis->ExternalRelease();
  66. }
  67.  
  68. STDMETHODIMP COleControl::XProvideClassInfo::QueryInterface(
  69.     REFIID iid, LPVOID* ppvObj)
  70. {
  71.     METHOD_PROLOGUE_EX_(COleControl, ProvideClassInfo)
  72.     return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  73. }
  74.  
  75. STDMETHODIMP COleControl::XProvideClassInfo::GetClassInfo(
  76.     LPTYPEINFO* ppTypeInfo)
  77. {
  78.     METHOD_PROLOGUE_EX(COleControl, ProvideClassInfo)
  79.  
  80.     CLSID clsid;
  81.     pThis->GetClassID(&clsid);
  82.  
  83.     return pThis->GetTypeInfoOfGuid(GetUserDefaultLCID(), clsid, ppTypeInfo);
  84. }
  85.  
  86. STDMETHODIMP COleControl::XProvideClassInfo::GetGUID(DWORD dwGuidKind,
  87.     GUID* pGUID)
  88. {
  89.     METHOD_PROLOGUE_EX_(COleControl, ProvideClassInfo)
  90.  
  91.     if (dwGuidKind == GUIDKIND_DEFAULT_SOURCE_DISP_IID)
  92.     {
  93.         *pGUID = *pThis->m_piidEvents;
  94.         return NOERROR;
  95.     }
  96.     else
  97.     {
  98.         *pGUID = GUID_NULL;
  99.         return E_INVALIDARG;
  100.     }
  101. }
  102.  
  103. /////////////////////////////////////////////////////////////////////////////
  104. // COleControl::XEventConnPt
  105.  
  106. void COleControl::XEventConnPt::OnAdvise(BOOL bAdvise)
  107. {
  108.     METHOD_PROLOGUE_EX(COleControl, EventConnPt)
  109.     pThis->OnEventAdvise(bAdvise);
  110. }
  111.  
  112. REFIID COleControl::XEventConnPt::GetIID()
  113. {
  114.     METHOD_PROLOGUE_EX_(COleControl, EventConnPt)
  115.     if (pThis->m_piidEvents != NULL)
  116.         return *(pThis->m_piidEvents);
  117.     else
  118.         return GUID_NULL;
  119. }
  120.  
  121. LPUNKNOWN COleControl::XEventConnPt::QuerySinkInterface(LPUNKNOWN pUnkSink)
  122. {
  123.     METHOD_PROLOGUE_EX_(COleControl, EventConnPt)
  124.  
  125.     // First, QI for control-specific IID; failing that, QI for IDispatch
  126.     LPUNKNOWN pUnkReturn = NULL;
  127.     if (FAILED(pUnkSink->QueryInterface(*(pThis->m_piidEvents),
  128.         reinterpret_cast<void**>(&pUnkReturn))))
  129.     {
  130.         pUnkSink->QueryInterface(IID_IDispatch,
  131.             reinterpret_cast<void**>(&pUnkReturn));
  132.     }
  133.     return pUnkReturn;
  134. }
  135.  
  136. /////////////////////////////////////////////////////////////////////////////
  137. // COleControl::OnEventAdvise - called by XEventConnPt::OnAdvise
  138.  
  139. void COleControl::OnEventAdvise(BOOL)
  140. {
  141.     // May be overridden by subclass
  142. }
  143.  
  144. /////////////////////////////////////////////////////////////////////////////
  145. // AfxConnectionAdvise
  146.  
  147. BOOL AFXAPI AfxConnectionAdvise(LPUNKNOWN pUnkSrc, REFIID iid,
  148.     LPUNKNOWN pUnkSink, BOOL bRefCount, DWORD* pdwCookie)
  149. {
  150.     ASSERT_POINTER(pUnkSrc, IUnknown);
  151.     ASSERT_POINTER(pUnkSink, IUnknown);
  152.     ASSERT_POINTER(pdwCookie, DWORD);
  153.  
  154.     BOOL bSuccess = FALSE;
  155.  
  156.     LPCONNECTIONPOINTCONTAINER pCPC;
  157.  
  158.     if (SUCCEEDED(pUnkSrc->QueryInterface(
  159.                     IID_IConnectionPointContainer,
  160.                     (LPVOID*)&pCPC)))
  161.     {
  162.         ASSERT_POINTER(pCPC, IConnectionPointContainer);
  163.  
  164.         LPCONNECTIONPOINT pCP;
  165.  
  166.         if (SUCCEEDED(pCPC->FindConnectionPoint(iid, &pCP)))
  167.         {
  168.             ASSERT_POINTER(pCP, IConnectionPoint);
  169.  
  170.             if (SUCCEEDED(pCP->Advise(pUnkSink, pdwCookie)))
  171.                 bSuccess = TRUE;
  172.  
  173.             pCP->Release();
  174.  
  175.             // The connection point just AddRef'ed us.  If we don't want to
  176.             // keep this reference count (because it would prevent us from
  177.             // being deleted; our reference count wouldn't go to zero), then
  178.             // we need to cancel the effects of the AddRef by calling
  179.             // Release.
  180.  
  181.             if (bSuccess && !bRefCount)
  182.                 pUnkSink->Release();
  183.         }
  184.  
  185.         pCPC->Release();
  186.     }
  187.  
  188.     return bSuccess;
  189. }
  190.  
  191. /////////////////////////////////////////////////////////////////////////////
  192. // AfxConnectionUnadvise
  193.  
  194. BOOL AFXAPI AfxConnectionUnadvise(LPUNKNOWN pUnkSrc, REFIID iid,
  195.     LPUNKNOWN pUnkSink, BOOL bRefCount, DWORD dwCookie)
  196. {
  197.     ASSERT_POINTER(pUnkSrc, IUnknown);
  198.     ASSERT_POINTER(pUnkSink, IUnknown);
  199.  
  200.     // When we call Unadvise, the connection point will Release us.  If we
  201.     // didn't keep the reference count when we called Advise, we need to
  202.     // AddRef now, to keep our reference count consistent.  Note that if
  203.     // the Unadvise fails, then we need to undo this extra AddRef by
  204.     // calling Release before we return.
  205.  
  206.     if (!bRefCount)
  207.         pUnkSink->AddRef();
  208.  
  209.     BOOL bSuccess = FALSE;
  210.  
  211.     LPCONNECTIONPOINTCONTAINER pCPC;
  212.  
  213.     if (SUCCEEDED(pUnkSrc->QueryInterface(
  214.                     IID_IConnectionPointContainer,
  215.                     (LPVOID*)&pCPC)))
  216.     {
  217.         ASSERT_POINTER(pCPC, IConnectionPointContainer);
  218.  
  219.         LPCONNECTIONPOINT pCP;
  220.  
  221.         if (SUCCEEDED(pCPC->FindConnectionPoint(iid, &pCP)))
  222.         {
  223.             ASSERT_POINTER(pCP, IConnectionPoint);
  224.  
  225.             if (SUCCEEDED(pCP->Unadvise(dwCookie)))
  226.                 bSuccess = TRUE;
  227.  
  228.             pCP->Release();
  229.         }
  230.  
  231.         pCPC->Release();
  232.     }
  233.  
  234.     // If we failed, undo the earlier AddRef.
  235.  
  236.     if (!bRefCount && !bSuccess)
  237.         pUnkSink->Release();
  238.  
  239.     return bSuccess;
  240. }
  241.  
  242. /////////////////////////////////////////////////////////////////////////////
  243. // Force any extra compiler-generated code into AFX_INIT_SEG
  244.  
  245. #ifdef AFX_INIT_SEG
  246. #pragma code_seg(AFX_INIT_SEG)
  247. #endif
  248.