home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 January / pcwk_01_1999.iso / Wtestowe / Vistdstd / Install / Data.Z / Addsink.CPP < prev    next >
C/C++ Source or Header  |  1997-11-11  |  6KB  |  300 lines

  1. /* ADDSINK.CPP - Implementation of a client side Visio Advise Sink.
  2.  * Copyright (C) 1991-1997 Visio Corporation. All rights reserved.
  3.  */
  4.  
  5. #include <windows.h>
  6. #include <ole2.h>
  7.  
  8. #if !defined (_WIN32)
  9.     #include <dispatch.h>
  10. #endif
  11.  
  12. #include "addsink.h"
  13. #include "vao.h"
  14.  
  15. /**************************************************************************
  16.  *+ CVisioAddonSink: INTERFACEDATA tables
  17.  */
  18.  
  19. // CVisioAddonSink virtual member indices - must be in the same order 
  20. // as virtual member functions.
  21. //
  22. enum IX_Sink
  23. {
  24.     IX_Sink_QueryInterface= 0,
  25.     IX_Sink_AddRef,
  26.     IX_Sink_Release,
  27.     IX_Sink_GetTypeInfoCount,
  28.     IX_Sink_GetTypeInfo,
  29.     IX_Sink_GetIDsOfNames,
  30.     IX_Sink_Invoke,
  31.     IX_Sink_VisEventProc,
  32.     IX_Sink_Dtor
  33. };
  34.  
  35. // CVisioAddonSink member ids. These are referenced in tables we feed to
  36. // CreateDispTypeInfo to get m_ptinfo. Set given values must be ids of those
  37. // members we want to dispatch to from Invoke. Values selected are arbitrary.
  38. //
  39. enum ID_Sink 
  40. {
  41.     ID_Sink_avail = DISPID_VALUE,    // don't squander default id.
  42.     ID_Sink_VisEventProc
  43. };
  44.  
  45. #define    SD(n)        static OLECHAR stc_Str##n[]= OLESTR(#n);
  46. #define    SR(n)        stc_Str##n
  47.  
  48. //    CreateDispTypeInfo() requires table
  49. // typeinfo structure that can be fed to standard dispatch services such 
  50. // as DispInvoke(). Table describes the set of methods we want Invoke()
  51. // to be able to dispatch to.
  52. //
  53. SD(VisEventProc)
  54.  
  55. SD(Event)
  56. SD(Source)
  57. SD(ID)
  58. SD(Seq)
  59. SD(Subject)
  60. SD(Extra)
  61.  
  62. static PARAMDATA rgpdataVisEventProc[]=
  63. {
  64.     {    SR(Event),    VT_I2         },
  65.     {    SR(Source),    VT_UNKNOWN    },
  66.     {    SR(ID),        VT_I4         },
  67.     {    SR(Seq),    VT_I4         },
  68.     {    SR(Subject),VT_UNKNOWN     },
  69.     {    SR(Extra),    VT_VARIANT     },
  70. };
  71.  
  72. static METHODDATA rgmdataSink[]=
  73. {
  74.     {
  75.         SR(VisEventProc),
  76.         rgpdataVisEventProc,
  77.         ID_Sink_VisEventProc,
  78.         IX_Sink_VisEventProc,
  79.         CC_STDCALL,
  80.         sizeof(rgpdataVisEventProc)/sizeof(rgpdataVisEventProc[0]),
  81.         DISPATCH_METHOD,
  82.         VT_EMPTY
  83.     }
  84. };
  85.  
  86. static INTERFACEDATA idataSink=
  87. {
  88.     rgmdataSink,
  89.     sizeof(rgmdataSink)/sizeof(rgmdataSink[0])
  90. };
  91.  
  92.  
  93. //    Shared type info ptr across all instances of CVisioAddonSink:
  94. ITypeInfo FAR *CVisioAddonSink::m_pInfo= NULL;
  95.  
  96.  
  97.  
  98. /**************************************************************************
  99.  *+ CVisioAddonSink: Implementation
  100.  */
  101.  
  102. CVisioAddonSink::CVisioAddonSink(LPVISEVENTPROC pCallback)
  103. {
  104.     HRESULT hr= NOERROR;
  105.  
  106.     m_pCallback= pCallback;
  107.  
  108.     m_cRef= 0;
  109.  
  110.  
  111.     // Call CreateDispTypeInfo() with tables describing methods we want
  112.     // Invoke to be able to dispatch to. Result is recorded in m_pInfo.
  113.     // This class does not assert m_pInfo. Other methods should gaurd
  114.     // against !m_pInfo.
  115.  
  116.     if (m_pInfo)
  117.     {
  118.         m_pInfo->AddRef();
  119.     }
  120.     else
  121.     {
  122.         hr= CreateDispTypeInfo(&idataSink, LOCALE_USER_DEFAULT, &m_pInfo);
  123.     }
  124.  
  125.    UNUSED_ARG(hr);
  126. }
  127.  
  128. CVisioAddonSink::~CVisioAddonSink()
  129. {
  130.     if ( m_pInfo )
  131.     {
  132.         if (0==m_pInfo->Release())
  133.             m_pInfo= NULL;    //    be sure not to leave dangling ptr if we were last hold on pInfo...
  134.     }
  135.  
  136.     // assert m_cRef==0
  137. }
  138.  
  139. STDMETHODIMP CVisioAddonSink::QueryInterface(REFIID riid, void FAR* FAR* ppv)
  140. {
  141.     if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch))
  142.     {
  143.         *ppv= this;
  144.         AddRef();
  145.         return NOERROR;
  146.     }
  147.     else
  148.     {
  149.         *ppv= NULL;
  150.         return ResultFromScode(E_NOINTERFACE);
  151.     }
  152. }
  153.  
  154. STDMETHODIMP_(ULONG) CVisioAddonSink::AddRef(void)
  155. {
  156.     m_cRef++;
  157.  
  158.     return m_cRef;
  159. }
  160.  
  161. STDMETHODIMP_(ULONG) CVisioAddonSink::Release(void)
  162. {
  163.     m_cRef--;
  164.  
  165.     if (m_cRef==0)
  166.     {
  167.         delete this;
  168.         return 0;
  169.     }
  170.     else
  171.     {
  172.         return m_cRef;
  173.     }
  174. }
  175.  
  176. STDMETHODIMP CVisioAddonSink::GetTypeInfoCount(
  177.     /* [out] */ UINT FAR* pctinfo)
  178. {
  179.     *pctinfo = 1;
  180.     return NOERROR;
  181. }
  182.  
  183. STDMETHODIMP CVisioAddonSink::GetTypeInfo(
  184.     /* [in] */ UINT itinfo,
  185.     /* [in] */ LCID lcid,
  186.     /* [out] */ ITypeInfo FAR* FAR* pptinfo)
  187. {
  188.     HRESULT hr= NOERROR;
  189.  
  190.    UNUSED_ARG(lcid);
  191.  
  192.     if ( pptinfo && m_pInfo )
  193.     {
  194.         if ( itinfo == 0 )
  195.         {
  196.             m_pInfo->AddRef();
  197.             *pptinfo= m_pInfo;
  198.         }
  199.         else
  200.         {
  201.             *pptinfo= NULL;
  202.             hr= ResultFromScode(DISP_E_BADINDEX);
  203.         }
  204.     }
  205.     else
  206.     {
  207.         hr= ResultFromScode(DISP_E_EXCEPTION);
  208.     }
  209.  
  210.     return hr;
  211. }
  212.  
  213. STDMETHODIMP CVisioAddonSink::GetIDsOfNames(
  214.     /* [in] */ REFIID riid,
  215.     /* [size_is][in] */ LPOLESTR FAR* rgszNames,
  216.     /* [in] */ UINT cNames,
  217.     /* [in] */ LCID lcid,
  218.     /* [size_is][out][in] */ DISPID FAR* rgdispid)
  219. {
  220.     HRESULT hr;
  221.  
  222.    UNUSED_ARG(&riid);
  223.     UNUSED_ARG(lcid);
  224.  
  225.     if ( m_pInfo )
  226.     {
  227.         hr= DispGetIDsOfNames(m_pInfo, rgszNames, cNames, rgdispid);
  228.     }
  229.     else
  230.     {
  231.         hr= ResultFromScode(DISP_E_EXCEPTION);
  232.     }
  233.  
  234.     return hr;
  235. }
  236.  
  237. STDMETHODIMP CVisioAddonSink::Invoke(
  238.     /* [in] */ DISPID dispidMember,
  239.     /* [in] */ REFIID riid,
  240.     /* [in] */ LCID lcid,
  241.     /* [in] */ WORD wFlags,
  242.     /* [unique][in] */ DISPPARAMS FAR* pdispparams,
  243.     /* [unique][out][in] */ VARIANT FAR* pvarResult,
  244.     /* [out] */ EXCEPINFO FAR* pexcepinfo,
  245.     /* [out] */ UINT FAR* puArgErr)
  246. {
  247.     HRESULT hr;
  248.  
  249.     UNUSED_ARG(&riid);
  250.    UNUSED_ARG(lcid);
  251.  
  252.     if ( m_pInfo )
  253.     {
  254.         hr= DispInvoke(this, m_pInfo, dispidMember,
  255.                              wFlags, pdispparams, pvarResult,
  256.                              pexcepinfo, puArgErr);
  257.     }
  258.     else
  259.     {
  260.         hr= ResultFromScode(DISP_E_EXCEPTION);
  261.     }
  262.  
  263.     return hr;
  264. }
  265.  
  266. STDMETHODIMP CVisioAddonSink::VisEventProc(
  267.     WORD             wEvent,            // i: id of interface to query for.
  268.     IUnknown FAR*    ipSource,        // i: object that is firing event.
  269.     DWORD            dwEventID,        // i: id of event that is firing.
  270.     DWORD            dwSeq,            // i: sequence number of event.
  271.     IUnknown FAR*     ipSubject,        // i: subject of this event.
  272.     VARIANT            vExtraInfo)        // i: other info. Usually nothing.
  273. {
  274.     HRESULT hr= NOERROR;
  275.  
  276.     if (m_pCallback)
  277.     {
  278.         hr= (*m_pCallback)(this, wEvent, ipSource, dwEventID, dwSeq, ipSubject, vExtraInfo);
  279.     }
  280.  
  281.     return hr;
  282. }
  283.  
  284. HRESULT CoCreateAddonSink(LPVISEVENTPROC pCallback, IUnknown FAR * FAR *ppSink)
  285. {
  286.     HRESULT hr= ResultFromScode(E_FAIL);
  287.  
  288.     //    assert ppSink!=NULL
  289.  
  290.     *ppSink= new CVisioAddonSink(pCallback);
  291.  
  292.     if (*ppSink)
  293.     {
  294.         (*ppSink)->AddRef();
  295.         hr= NOERROR;
  296.     }
  297.  
  298.     return hr;
  299. }
  300.