home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / atl / circcoll / objects.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  4KB  |  180 lines

  1. // objects.cpp : collection implementation
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #include "precircc.h"
  14.  
  15. #include "CircColl.h"
  16. #include "objects.h"
  17.  
  18. /////////////////////////////////////////////////////////////////////////////
  19. // class CMyCircle
  20.  
  21.  
  22. CMyCircle::CMyCircle()
  23. {
  24.     m_xCenter = 0;
  25.     m_yCenter = 0;
  26.     m_Radius = 0;
  27. }
  28.  
  29. // IMyCircle Implementation
  30.  
  31. STDMETHODIMP CMyCircle::get_XCenter(double* pXCenter)
  32. {
  33.     if (pXCenter == NULL)
  34.         return E_POINTER;
  35.     *pXCenter = m_xCenter;
  36.     return S_OK;
  37. }
  38.  
  39. STDMETHODIMP CMyCircle::put_XCenter(double xCenter)
  40. {
  41.     m_xCenter = xCenter;
  42.     return S_OK;
  43. }
  44.  
  45. STDMETHODIMP CMyCircle::get_YCenter(double* pYCenter)
  46. {
  47.     if (pYCenter == NULL)
  48.         return E_POINTER;
  49.     *pYCenter = m_yCenter;
  50.     return S_OK;
  51. }
  52.  
  53. STDMETHODIMP CMyCircle::put_YCenter(double yCenter)
  54. {
  55.     m_yCenter = yCenter;
  56.     return S_OK;
  57. }
  58.  
  59. STDMETHODIMP CMyCircle::get_Radius(double* pRadius)
  60. {
  61.     if (pRadius == NULL)
  62.         return E_POINTER;
  63.     *pRadius = m_Radius;
  64.     return S_OK;
  65. }
  66.  
  67.  
  68. STDMETHODIMP CMyCircle::put_Radius(double Radius)
  69. {
  70.     m_Radius = Radius;
  71.     return S_OK;
  72. }
  73.  
  74. STDMETHODIMP CMyCircle::put_Label(BSTR bstrLabel)
  75. {
  76.     USES_CONVERSION;
  77.     m_bstrLabel = bstrLabel;
  78.     return S_OK;
  79. }
  80.  
  81. STDMETHODIMP CMyCircle::get_Label(BSTR* pbstrLabel)
  82. {
  83.     USES_CONVERSION;
  84.     if (pbstrLabel == NULL)
  85.         return E_POINTER;
  86.     *pbstrLabel = m_bstrLabel.Copy();
  87.     return S_OK;
  88. }
  89.  
  90. ///////////////////////////////////////////////////////////////////////////
  91. // class CMyCircleCollectionCreator
  92.  
  93. STDMETHODIMP CMyCircleCollectionCreator::GetCircles(short n, VARIANT* retval)
  94. {
  95.     VariantInit(retval);
  96.  
  97.     CComObject<CMyCircleCollection>* p = new CComObject<CMyCircleCollection>;
  98.     p->Init(n);
  99.     IDispatch* pDisp;
  100.     p->QueryInterface(IID_IDispatch, (void**)&pDisp);
  101.     ATLASSERT(pDisp);
  102.     retval->vt = VT_DISPATCH;
  103.     retval->pdispVal = pDisp;
  104.     return S_OK;
  105. }
  106.  
  107. ///////////////////////////////////////////////////////////////////////////
  108. // class CMyCircleCollection
  109.  
  110. STDMETHODIMP CMyCircleCollection::get_Count(long* retval)
  111. {
  112.     if (retval == NULL)
  113.         return E_POINTER;
  114.     *retval = m_nSize;
  115.     return S_OK;
  116. }
  117.  
  118. STDMETHODIMP CMyCircleCollection::get_Item(long Index, VARIANT* retval)
  119. {
  120.     if (retval == NULL)
  121.         return E_POINTER;
  122.     VariantInit(retval);
  123.     retval->vt = VT_UNKNOWN;
  124.     retval->punkVal = NULL;
  125.     // use 1-based index, VB like
  126.     if ((Index < 1) || (Index > m_nSize))
  127.         return E_INVALIDARG;
  128.     VariantCopy(retval, &m_VarVect[Index-1]);
  129.     return S_OK;
  130. }
  131.  
  132. STDMETHODIMP CMyCircleCollection::get__NewEnum(IUnknown** retval)
  133. {
  134.     if (retval == NULL)
  135.         return E_POINTER;
  136.     *retval = NULL;
  137.     typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > enumvar;
  138.     enumvar* p = new enumvar;
  139.     ATLASSERT(p);
  140.     HRESULT hRes = p->Init(&m_VarVect[0], &m_VarVect[m_nSize], NULL, AtlFlagCopy);
  141.     if (SUCCEEDED(hRes))
  142.         hRes = p->QueryInterface(IID_IEnumVARIANT, (void**)retval);
  143.     if (FAILED(hRes))
  144.         delete p;
  145.     return hRes;
  146. }
  147.  
  148.  
  149. void CMyCircleCollection::Init(short n)
  150. {
  151.     if (m_VarVect != NULL)
  152.         delete [] m_VarVect;
  153.     m_nSize = n;
  154.     m_VarVect = new CComVariant[n];
  155.     for (int i=0; i<n; i++)
  156.     {
  157.         // create an object
  158.         CComObject<CMyCircle>* pCircle;
  159.         HRESULT hRes = CComObject<CMyCircle>::CreateInstance(&pCircle);
  160.         ATLASSERT(SUCCEEDED(hRes));
  161.  
  162.         // set arbitrary values
  163.         pCircle->m_Radius = 10*(i+1) + 50;
  164.         pCircle->m_xCenter = pCircle->m_yCenter = 2*pCircle->m_Radius;
  165.         TCHAR szBuf[100];
  166.         wsprintf(szBuf,_T("Circle # %d"),i+1);  // start from 1, VB like
  167.         pCircle->m_bstrLabel = szBuf;
  168.  
  169.         // get IDispatch pointer
  170.         LPDISPATCH lpDisp = NULL;
  171.         pCircle->QueryInterface(IID_IDispatch, (void**)&lpDisp);
  172.         ATLASSERT(lpDisp);
  173.  
  174.         // create a variant and add it to the collection
  175.         CComVariant& var = m_VarVect[i];
  176.         var.vt = VT_DISPATCH;
  177.         var.pdispVal = lpDisp;
  178.     }
  179. }
  180.