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 / control.cpp next >
C/C++ Source or Header  |  1995-05-03  |  17KB  |  789 lines

  1. /*
  2.  * CONTROL.CPP
  3.  * Polyline Chapter 24
  4.  *
  5.  * Additional interfaces above the Chapter 23 version of Polyline
  6.  * to make it an OLE Control, specifically ISpecifyPropertyPages,
  7.  * IProvideClassInfo, IOleControl, and IDispatch, none of which
  8.  * are terribly complex.
  9.  *
  10.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  11.  *
  12.  * Kraig Brockschmidt, Microsoft
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "polyline.h"
  19.  
  20.  
  21. //ISpecifyPropertyPages implementation
  22. /*
  23.  * CImpISpecifyPP::CImpISpecifyPP
  24.  * CImpISpecifyPP::~CImpISpecifyPP
  25.  *
  26.  * Parameters (Constructor):
  27.  *  pObj            PCPolyline of the object we're in.
  28.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  29.  */
  30.  
  31. CImpISpecifyPP::CImpISpecifyPP(PCPolyline pObj, LPUNKNOWN pUnkOuter)
  32.     {
  33.     m_cRef=0;
  34.     m_pObj=pObj;
  35.     m_pUnkOuter=pUnkOuter;
  36.     return;
  37.     }
  38.  
  39. CImpISpecifyPP::~CImpISpecifyPP(void)
  40.     {
  41.     return;
  42.     }
  43.  
  44.  
  45. /*
  46.  * CImpISpecifyPP::QueryInterface
  47.  * CImpISpecifyPP::AddRef
  48.  * CImpISpecifyPP::Release
  49.  */
  50.  
  51. STDMETHODIMP CImpISpecifyPP::QueryInterface(REFIID riid
  52.     , LPVOID *ppv)
  53.     {
  54.     return m_pUnkOuter->QueryInterface(riid, ppv);
  55.     }
  56.  
  57. STDMETHODIMP_(ULONG) CImpISpecifyPP::AddRef(void)
  58.     {
  59.     ++m_cRef;
  60.     return m_pUnkOuter->AddRef();
  61.     }
  62.  
  63. STDMETHODIMP_(ULONG) CImpISpecifyPP::Release(void)
  64.     {
  65.     --m_cRef;
  66.     return m_pUnkOuter->Release();
  67.     }
  68.  
  69.  
  70.  
  71. /*
  72.  * CImpISpecifyPP::GetPages
  73.  *
  74.  * Purpose:
  75.  *  Returns an array of GUIDs identifying the indivudual property
  76.  *  pages used for this object.
  77.  *
  78.  * Parameters:
  79.  *  pPages          CAUUID * pointing to a counted array of GUIDs.
  80.  *                  This function allocates the array elements
  81.  *                  and stores them in this structure.
  82.  */
  83.  
  84. STDMETHODIMP CImpISpecifyPP::GetPages(CAUUID *pPages)
  85.     {
  86.     IMalloc *pIMalloc;
  87.     GUID    *pGUID;
  88.  
  89.     pPages->cElems=0;
  90.     pPages->pElems=NULL;
  91.  
  92.     if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  93.         return ResultFromScode(E_OUTOFMEMORY);
  94.  
  95.     pGUID=(GUID *)pIMalloc->Alloc(CPROPPAGES * sizeof(GUID));
  96.  
  97.     if (NULL!=pGUID)
  98.         {
  99.         //We use our own page plus the standard color page.
  100.         pGUID[0]=CLSID_PolylinePropPage;
  101.  
  102.         //Fill the structure and return.
  103.         pPages->cElems=CPROPPAGES;
  104.         pPages->pElems=pGUID;
  105.         }
  106.  
  107.     pIMalloc->Release();
  108.     return (NULL!=pGUID) ? NOERROR
  109.         : ResultFromScode(E_OUTOFMEMORY);
  110.     }
  111.  
  112.  
  113.  
  114.  
  115. //IProvideClassInfo interface implementation
  116. /*
  117.  * CImpIProvideClassInfo::CImpIProvideClassInfo
  118.  * CImpIProvideClassInfo::~CImpIProvideClassInfo
  119.  *
  120.  * Parameters (Constructor):
  121.  *  pObj            PCPolyline of the object we're in.
  122.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  123.  */
  124.  
  125. CImpIProvideClassInfo::CImpIProvideClassInfo(PCPolyline pObj
  126.     , LPUNKNOWN pUnkOuter)
  127.     {
  128.     m_cRef=0;
  129.     m_pObj=pObj;
  130.     m_pUnkOuter=pUnkOuter;
  131.     return;
  132.     }
  133.  
  134. CImpIProvideClassInfo::~CImpIProvideClassInfo(void)
  135.     {
  136.     return;
  137.     }
  138.  
  139.  
  140.  
  141. /*
  142.  * CImpIProvideClassInfo::QueryInterface
  143.  * CImpIProvideClassInfo::AddRef
  144.  * CImpIProvideClassInfo::Release
  145.  */
  146.  
  147. STDMETHODIMP CImpIProvideClassInfo::QueryInterface(REFIID riid
  148.     , LPVOID *ppv)
  149.     {
  150.     return m_pUnkOuter->QueryInterface(riid, ppv);
  151.     }
  152.  
  153. STDMETHODIMP_(ULONG) CImpIProvideClassInfo::AddRef(void)
  154.     {
  155.     ++m_cRef;
  156.     return m_pUnkOuter->AddRef();
  157.     }
  158.  
  159. STDMETHODIMP_(ULONG) CImpIProvideClassInfo::Release(void)
  160.     {
  161.     --m_cRef;
  162.     return m_pUnkOuter->Release();
  163.     }
  164.  
  165.  
  166.  
  167. /*
  168.  * CImpIProvideClassInfo::GetClassInfo
  169.  *
  170.  * Purpose:
  171.  *  Returns the ITypeInfo through which the caller can retrieve
  172.  *  information about the entire object.
  173.  *
  174.  * Parameters:
  175.  *  ppTI            LPTYPEINFO * in which to store the ITypeInfo
  176.  *                  pointer.
  177.  */
  178.  
  179. STDMETHODIMP CImpIProvideClassInfo::GetClassInfo(LPTYPEINFO *ppTI)
  180.     {
  181.     if (NULL==ppTI)
  182.         return ResultFromScode(E_POINTER);
  183.  
  184.     *ppTI=NULL;
  185.  
  186.     return m_pObj->m_pITypeLib->GetTypeInfoOfGuid(CLSID_Polyline19
  187.         , ppTI);
  188.     }
  189.  
  190.  
  191.  
  192.  
  193. //IDispatch interface implementation
  194.  
  195. /*
  196.  * CImpIDispatch::CImpIDispatch
  197.  * CImpIDispatch::~CImpIDispatch
  198.  *
  199.  * Parameters (Constructor):
  200.  *  pObj            PCPolyline of the object we're in.
  201.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  202.  */
  203.  
  204. CImpIDispatch::CImpIDispatch(PCPolyline pObj, LPUNKNOWN pUnkOuter)
  205.     {
  206.     m_cRef=0;
  207.     m_pObj=pObj;
  208.     m_pUnkOuter=pUnkOuter;
  209.     return;
  210.     }
  211.  
  212. CImpIDispatch::~CImpIDispatch(void)
  213.     {
  214.     return;
  215.     }
  216.  
  217.  
  218.  
  219. /*
  220.  * CImpIDispatch::QueryInterface
  221.  * CImpIDispatch::AddRef
  222.  * CImpIDispatch::Release
  223.  */
  224.  
  225. STDMETHODIMP CImpIDispatch::QueryInterface(REFIID riid, PPVOID ppv)
  226.     {
  227.     return m_pUnkOuter->QueryInterface(riid, ppv);
  228.     }
  229.  
  230.  
  231. STDMETHODIMP_(ULONG) CImpIDispatch::AddRef(void)
  232.     {
  233.     ++m_cRef;
  234.     return m_pUnkOuter->AddRef();
  235.     }
  236.  
  237. STDMETHODIMP_(ULONG) CImpIDispatch::Release(void)
  238.     {
  239.     --m_cRef;
  240.     return m_pUnkOuter->Release();
  241.     }
  242.  
  243.  
  244.  
  245. /*
  246.  * CImpIDispatch::GetTypeInfoCount
  247.  * CImpIDispatch::GetTypeInfo
  248.  * CImpIDispatch::GetIDsOfNames
  249.  *
  250.  * The usual
  251.  */
  252.  
  253. STDMETHODIMP CImpIDispatch::GetTypeInfoCount(UINT *pctInfo)
  254.     {
  255.     //We implement GetTypeInfo so return 1
  256.     *pctInfo=1;
  257.     return NOERROR;
  258.     }
  259.  
  260.  
  261. STDMETHODIMP CImpIDispatch::GetTypeInfo(UINT itInfo, LCID lcid
  262.     , ITypeInfo **ppITypeInfo)
  263.     {
  264.     if (0!=itInfo)
  265.         return ResultFromScode(TYPE_E_ELEMENTNOTFOUND);
  266.  
  267.     if (NULL==ppITypeInfo)
  268.         return ResultFromScode(E_POINTER);
  269.  
  270.     *ppITypeInfo=NULL;
  271.  
  272.     //We ignore the LCID
  273.     return m_pObj->m_pITypeLib->GetTypeInfoOfGuid
  274.         (DIID_DIPolylineControl, ppITypeInfo);
  275.     }
  276.  
  277.  
  278. STDMETHODIMP CImpIDispatch::GetIDsOfNames(REFIID riid
  279.     , OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispID)
  280.     {
  281.     HRESULT     hr;
  282.     ITypeInfo  *pTI;
  283.  
  284.     if (IID_NULL!=riid)
  285.         return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
  286.  
  287.     hr=GetTypeInfo(0, lcid, &pTI);
  288.  
  289.     if (SUCCEEDED(hr))
  290.         {
  291.         hr=DispGetIDsOfNames(pTI, rgszNames, cNames, rgDispID);
  292.         pTI->Release();
  293.         }
  294.  
  295.     return hr;
  296.     }
  297.  
  298.  
  299.  
  300. /*
  301.  * CImpIDispatch::Invoke
  302.  *
  303.  * Purpose:
  304.  *  Calls a method in the dispatch interface or manipulates a
  305.  *  property.
  306.  *
  307.  * Parameters:
  308.  *  dispID          DISPID of the method or property of interest.
  309.  *  riid            REFIID reserved, must be IID_NULL.
  310.  *  lcid            LCID of the locale.
  311.  *  wFlags          USHORT describing the context of the invocation.
  312.  *  pDispParams     DISPPARAMS * to the array of arguments.
  313.  *  pVarResult      VARIANT * in which to store the result.  Is
  314.  *                  NULL if the caller is not interested.
  315.  *  pExcepInfo      EXCEPINFO * to exception information.
  316.  *  puArgErr        UINT * in which to store the index of an
  317.  *                  invalid parameter if DISP_E_TYPEMISMATCH
  318.  *                  is returned.
  319.  *
  320.  * Return Value:
  321.  *  HRESULT         NOERROR or a general error code.
  322.  */
  323.  
  324. STDMETHODIMP CImpIDispatch::Invoke(DISPID dispID, REFIID riid
  325.     , LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams
  326.     , VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
  327.     {
  328.     HRESULT     hr;
  329.     ITypeInfo  *pTI;
  330.  
  331.     //riid is supposed to be IID_NULL always
  332.     if (IID_NULL!=riid)
  333.         return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
  334.  
  335.     //Get the ITypeInfo for lcid
  336.     hr=GetTypeInfo(0, lcid, &pTI);
  337.  
  338.     if (FAILED(hr))
  339.         return hr;
  340.  
  341.     hr=pTI->Invoke(m_pObj->m_pImpIPolylineControl, dispID, wFlags
  342.         , pDispParams, pVarResult, pExcepInfo, puArgErr);
  343.  
  344.     pTI->Release();
  345.     return hr;
  346.     }
  347.  
  348.  
  349.  
  350. //IPolylineControl interface implementation
  351.  
  352. /*
  353.  * CImpIPolylineControl::CImpIPolylineControl
  354.  * CImpIPolylineControl::~CImpIPolylineControl
  355.  *
  356.  * Parameters (Constructor):
  357.  *  pObj            PCPolyline of the object we're in.
  358.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  359.  */
  360.  
  361. CImpIPolylineControl::CImpIPolylineControl(PCPolyline pObj
  362.     , LPUNKNOWN pUnkOuter)
  363.     {
  364.     m_cRef=0;
  365.     m_pObj=pObj;
  366.     m_pUnkOuter=pUnkOuter;
  367.     return;
  368.     }
  369.  
  370. CImpIPolylineControl::~CImpIPolylineControl(void)
  371.     {
  372.     return;
  373.     }
  374.  
  375.  
  376.  
  377. /*
  378.  * CImpIPolylineControl::QueryInterface
  379.  * CImpIPolylineControl::AddRef
  380.  * CImpIPolylineControl::Release
  381.  */
  382.  
  383. STDMETHODIMP CImpIPolylineControl::QueryInterface(REFIID riid
  384.     , LPVOID *ppv)
  385.     {
  386.     return m_pUnkOuter->QueryInterface(riid, ppv);
  387.     }
  388.  
  389. STDMETHODIMP_(ULONG) CImpIPolylineControl::AddRef(void)
  390.     {
  391.     ++m_cRef;
  392.     return m_pUnkOuter->AddRef();
  393.     }
  394.  
  395. STDMETHODIMP_(ULONG) CImpIPolylineControl::Release(void)
  396.     {
  397.     --m_cRef;
  398.     return m_pUnkOuter->Release();
  399.     }
  400.  
  401.  
  402.  
  403. /*
  404.  * CImpIPolylineControl::BackColor
  405.  * CImpIPolylineControl::LineColor
  406.  * CImpIPolylineControl::LineStyle
  407.  * CImpIPolylineControl::Clear
  408.  * CImpIPolylineControl::RemoveLastPoint
  409.  *
  410.  * Purpose:
  411.  *  Dispatch interface entry points that map to IPolyline
  412.  *  members.
  413.  */
  414.  
  415. STDMETHODIMP_(void) CImpIPolylineControl::put_BackColor
  416.     (OLE_COLOR cr)
  417.     {
  418.     COLORREF        crOld;
  419.  
  420.     m_pObj->m_pImpIPolyline->ColorSet(POLYLINECOLOR_BACKGROUND
  421.         , cr, &crOld);
  422.     return;
  423.     }
  424.  
  425. STDMETHODIMP_(OLE_COLOR) CImpIPolylineControl::get_BackColor(void)
  426.     {
  427.     COLORREF        cr;
  428.  
  429.     m_pObj->m_pImpIPolyline->ColorGet(POLYLINECOLOR_BACKGROUND
  430.         , &cr);
  431.  
  432.     return cr;
  433.     }
  434.  
  435. STDMETHODIMP_(void) CImpIPolylineControl::put_LineColor
  436.     (OLE_COLOR cr)
  437.     {
  438.     COLORREF        crOld;
  439.  
  440.     m_pObj->m_pImpIPolyline->ColorSet(POLYLINECOLOR_LINE
  441.         , cr, &crOld);
  442.  
  443.     return;
  444.     }
  445.  
  446. STDMETHODIMP_(OLE_COLOR) CImpIPolylineControl::get_LineColor(void)
  447.     {
  448.     COLORREF        cr;
  449.  
  450.     m_pObj->m_pImpIPolyline->ColorGet(POLYLINECOLOR_LINE, &cr);
  451.     return cr;
  452.     }
  453.  
  454. STDMETHODIMP_(void) CImpIPolylineControl::put_LineStyle
  455.     (short iStyle)
  456.     {
  457.     UINT    i;
  458.  
  459.     m_pObj->m_pImpIPolyline->LineStyleSet(iStyle, &i);
  460.     return;
  461.     }
  462.  
  463. STDMETHODIMP_(short) CImpIPolylineControl::get_LineStyle(void)
  464.     {
  465.     UINT    iStyle;
  466.  
  467.     m_pObj->m_pImpIPolyline->LineStyleGet(&iStyle);
  468.     return (short)iStyle;
  469.     }
  470.  
  471. STDMETHODIMP CImpIPolylineControl::Clear(void)
  472.     {
  473.     return m_pObj->m_pImpIPolyline->New();
  474.     }
  475.  
  476. STDMETHODIMP CImpIPolylineControl::RemoveLastPoint(void)
  477.     {
  478.     return m_pObj->m_pImpIPolyline->Undo();
  479.     }
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486. //IOleControl interface implementation
  487.  
  488. /*
  489.  * CImpIOleControl::CImpIOleControl
  490.  * CImpIOleControl::~CImpIOleControl
  491.  *
  492.  * Parameters (Constructor):
  493.  *  pObj            PCPolyline of the object we're in.
  494.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  495.  */
  496.  
  497. CImpIOleControl::CImpIOleControl(PCPolyline pObj
  498.     , LPUNKNOWN pUnkOuter)
  499.     {
  500.     m_cRef=0;
  501.     m_pObj=pObj;
  502.     m_pUnkOuter=pUnkOuter;
  503.     return;
  504.     }
  505.  
  506. CImpIOleControl::~CImpIOleControl(void)
  507.     {
  508.     return;
  509.     }
  510.  
  511.  
  512.  
  513. /*
  514.  * CImpIOleControl::QueryInterface
  515.  * CImpIOleControl::AddRef
  516.  * CImpIOleControl::Release
  517.  */
  518.  
  519. STDMETHODIMP CImpIOleControl::QueryInterface(REFIID riid
  520.     , LPVOID *ppv)
  521.     {
  522.     return m_pUnkOuter->QueryInterface(riid, ppv);
  523.     }
  524.  
  525. STDMETHODIMP_(ULONG) CImpIOleControl::AddRef(void)
  526.     {
  527.     ++m_cRef;
  528.     return m_pUnkOuter->AddRef();
  529.     }
  530.  
  531. STDMETHODIMP_(ULONG) CImpIOleControl::Release(void)
  532.     {
  533.     --m_cRef;
  534.     return m_pUnkOuter->Release();
  535.     }
  536.  
  537.  
  538.  
  539. /*
  540.  * CImpIOleControl::GetControlInfo
  541.  *
  542.  * Purpose:
  543.  *  Fills a CONTROLINFO structure containing information about
  544.  *  the controls mnemonics and other behavioral aspects.
  545.  *
  546.  * Parameters:
  547.  *  pCI             LPCONTROLINFO to the structure to fill
  548.  */
  549.  
  550. STDMETHODIMP CImpIOleControl::GetControlInfo(LPCONTROLINFO pCI)
  551.     {
  552.     if (NULL==pCI)
  553.         return ResultFromScode(E_INVALIDARG);
  554.  
  555.     *pCI=m_pObj->m_ctrlInfo;
  556.     return ResultFromScode(E_NOTIMPL);
  557.     }
  558.  
  559.  
  560.  
  561.  
  562. /*
  563.  * CImpIOleControl::OnMnemonic
  564.  *
  565.  * Purpose:
  566.  *  Notifies the control that a mnemonic was activated.
  567.  *
  568.  * Parameters:
  569.  *  pMsg            LPMSG containing the message that matches one of
  570.  *                  the control's mnemonics.  The control uses this
  571.  *                  to distinguish which mnemonic was pressed.
  572.  */
  573.  
  574. STDMETHODIMP CImpIOleControl::OnMnemonic(LPMSG pMsg)
  575.     {
  576.     //No mnemonics
  577.     return NOERROR;
  578.     }
  579.  
  580.  
  581.  
  582.  
  583.  
  584. /*
  585.  * CImpIOleControl::OnAmbientPropertyChange
  586.  *
  587.  * Purpose:
  588.  *  Notifies the control that one or more of the container's ambient
  589.  *  properties changed.
  590.  *
  591.  * Parameters:
  592.  *  dispID          DISPID identifying the property, which can
  593.  *                  be DISPID_UNKNOWN indicating that more than
  594.  *                  one changed.
  595.  */
  596.  
  597. STDMETHODIMP CImpIOleControl::OnAmbientPropertyChange(DISPID dispID)
  598.     {
  599.     /*
  600.      * We detect any change in UIDead or ShowHatching.  Changes
  601.      * in container colors do not affect us as we only use those
  602.      * for initial values.
  603.      */
  604.  
  605.     switch (dispID)
  606.         {
  607.         case DISPID_UNKNOWN:
  608.             m_pObj->AmbientsInitialize(INITAMBIENT_SHOWHATCHING
  609.                 | INITAMBIENT_UIDEAD);
  610.             break;
  611.  
  612.         case DISPID_AMBIENT_SHOWHATCHING:
  613.             m_pObj->AmbientsInitialize(INITAMBIENT_SHOWHATCHING);
  614.             break;
  615.  
  616.         case DISPID_AMBIENT_UIDEAD:
  617.             m_pObj->AmbientsInitialize(INITAMBIENT_UIDEAD);
  618.             break;
  619.         }
  620.  
  621.     return NOERROR;
  622.     }
  623.  
  624.  
  625.  
  626.  
  627. /*
  628.  * CImpIOleControl::FreezeEvents
  629.  *
  630.  * Purpose:
  631.  *  Instructs the control to stop firing events or to continue
  632.  *  firing them.
  633.  *
  634.  * Parameters:
  635.  *  fFreeze         BOOL indicating to freeze (TRUE) or thaw (FALSE)
  636.  *                  events from this control.
  637.  */
  638.  
  639. STDMETHODIMP CImpIOleControl::FreezeEvents(BOOL fFreeze)
  640.     {
  641.     m_pObj->m_fFreezeEvents=fFreeze;
  642.     return NOERROR;
  643.     }
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650. //CAdviseRouter class implementation
  651. /*
  652.  * CAdviseRouter::CAdviseRouter
  653.  * CAdviseRouter::~CAdviseRouter
  654.  *
  655.  * Constructor Parameters:
  656.  *  pIDispatch      IDispatch * to which we route notifications.
  657.  *  pObj            PCPolyline to the control itself.
  658.  */
  659.  
  660. CAdviseRouter::CAdviseRouter(IDispatch *pIDispatch
  661.     , PCPolyline pObj)
  662.     {
  663.     m_cRef=0;
  664.     m_pObj=pObj;
  665.     m_pIDispatch=pIDispatch;
  666.     return;
  667.     }
  668.  
  669.  
  670. CAdviseRouter::~CAdviseRouter(void)
  671.     {
  672.     ReleaseInterface(m_pIDispatch);
  673.     return;
  674.     }
  675.  
  676.  
  677.  
  678.  
  679. /*
  680.  * CAdviseRouter::QueryInterface
  681.  * CAdviseRouter::AddRef
  682.  * CAdviseRouter::Release
  683.  *
  684.  * Purpose:
  685.  *  IUnknown members for this IPolylineAdviseSink implementations.
  686.  */
  687.  
  688. STDMETHODIMP CAdviseRouter::QueryInterface(REFIID riid
  689.     , PPVOID ppv)
  690.     {
  691.     *ppv=NULL;
  692.  
  693.     if (IID_IUnknown==riid || IID_IPolylineAdviseSink10==riid)
  694.         {
  695.         *ppv=this;
  696.         AddRef();
  697.         return NOERROR;
  698.         }
  699.  
  700.     return ResultFromScode(E_NOINTERFACE);
  701.     }
  702.  
  703.  
  704. STDMETHODIMP_(ULONG) CAdviseRouter::AddRef(void)
  705.     {
  706.     return ++m_cRef;
  707.     }
  708.  
  709.  
  710. STDMETHODIMP_(ULONG) CAdviseRouter::Release(void)
  711.     {
  712.     if (0L!=--m_cRef)
  713.         return m_cRef;
  714.  
  715.     delete this;
  716.     return 0;
  717.     }
  718.  
  719.  
  720.  
  721.  
  722. /*
  723.  * CAdviseRouter::OnPointChange
  724.  * CAdviseRouter::OnSizeChange
  725.  * CAdviseRouter::OnColorChange
  726.  * CAdviseRouter::OnLineStyleChange
  727.  *
  728.  * Purpose:
  729.  *  Invokes the same member in the IDispatch pointer we hold.
  730.  */
  731.  
  732. STDMETHODIMP_(void) CAdviseRouter::OnPointChange(void)
  733.     {
  734.     Invoke(EVENT_ONPOINTCHANGE);
  735.     return;
  736.     }
  737.  
  738. STDMETHODIMP_(void) CAdviseRouter::OnSizeChange(void)
  739.     {
  740.     Invoke(EVENT_ONSIZECHANGE);
  741.     return;
  742.     }
  743.  
  744.  
  745. STDMETHODIMP_(void) CAdviseRouter::OnColorChange(void)
  746.     {
  747.     Invoke(EVENT_ONCOLORCHANGE);
  748.     return;
  749.     }
  750.  
  751.  
  752. STDMETHODIMP_(void) CAdviseRouter::OnLineStyleChange(void)
  753.     {
  754.     Invoke(EVENT_ONLINESTYLECHANGE);
  755.     return;
  756.     }
  757.  
  758.  
  759.  
  760.  
  761. /*
  762.  * CAdviseRouter::Invoke
  763.  *
  764.  * Purpose:
  765.  *  Calls IDispatch::Invoke for any of the events we handle.
  766.  *  None of these have any arguments.
  767.  *
  768.  * Parameters:
  769.  *  dispID          DISPID of the event to fire.
  770.  *
  771.  * Return Value:
  772.  *  None
  773.  */
  774.  
  775. void CAdviseRouter::Invoke(DISPID dispID)
  776.     {
  777.     DISPPARAMS  dp;
  778.     VARIANT     va;
  779.  
  780.     if (m_pObj->m_fFreezeEvents)
  781.         return;
  782.  
  783.     m_pIDispatch->Invoke(dispID, IID_NULL
  784.         , LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dp
  785.         , &va, NULL, NULL);
  786.  
  787.     return;
  788.     }
  789.