home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / browseh / collect.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-31  |  6.2 KB  |  243 lines

  1. /*************************************************************************
  2. **
  3. **  This is a part of the Microsoft Source Code Samples.
  4. **
  5. **  Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  6. **
  7. **  This source code is only intended as a supplement to Microsoft Development
  8. **  Tools and/or WinHelp documentation.  See these sources for detailed
  9. **  information regarding the Microsoft samples programs.
  10. **
  11. **  OLE Automation TypeLibrary Browse Helper Sample
  12. **
  13. **  collect.cpp
  14. **
  15. **  CCollection implementation
  16. **
  17. **  Written by Microsoft Product Support Services, Windows Developer Support
  18. **
  19. *************************************************************************/
  20.  
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #ifdef WIN16   
  24.   #include <ole2.h>
  25.   #include <compobj.h>    
  26.   #include <dispatch.h> 
  27.   #include <variant.h>
  28.   #include <olenls.h>  
  29. #endif   
  30. #include "browseh.h"  
  31.  
  32. /*
  33.  * CCollection::Create
  34.  *
  35.  * Purpose:
  36.  *  Creates an instance of a collection object and initializes it.
  37.  *
  38.  * Parameters:
  39.  *  lMaxSize   Maximum number of items that can added to collection.
  40.  *  lLBound    Lower bound of index of collection.  
  41.  *  ppCollection    Returns collection object.
  42.  *
  43.  * Return Value:
  44.  *  HRESULT
  45.  *
  46.  */
  47. HRESULT 
  48. CCollection::Create(ULONG lMaxSize, long lLBound, CCollection FAR* FAR* ppCollection) 
  49. {   
  50.     HRESULT hr;
  51.     CCollection FAR* pCollection = NULL;
  52.     SAFEARRAYBOUND sabound[1];
  53.      
  54.     *ppCollection = NULL;
  55.     
  56.     // Create new collection
  57.     pCollection = new CCollection();
  58.     if (pCollection == NULL)
  59.         goto error; 
  60.     // Load type information for the collection from type library. 
  61.     hr = pCollection->LoadTypeInfo(IID_ICollection);
  62.     if (FAILED(hr))
  63.         goto error;
  64.     
  65.     // If lMaxSize is 0 increment it to 1 or SafeArrayCreate will fail
  66.     if (lMaxSize == 0)   
  67.        lMaxSize = 1;       
  68.     pCollection->m_cMax = lMaxSize;
  69.     pCollection->m_cElements = 0; 
  70.     pCollection->m_lLBound = lLBound;
  71.  
  72.     // Create a safe array which is used to implement the collection   
  73.     sabound[0].cElements = lMaxSize;
  74.     sabound[0].lLbound = lLBound;        
  75.     pCollection->m_psa = SafeArrayCreate(VT_VARIANT, 1, sabound);
  76.     if (pCollection->m_psa == NULL)
  77.     {
  78.         hr = E_OUTOFMEMORY;
  79.         goto error;
  80.     }
  81.     
  82. #ifdef _DEBUG  
  83.     lstrcpyn(pCollection->m_szClassName, TEXT("Collection"), 100);
  84. #endif          
  85.  
  86.     *ppCollection = pCollection;
  87.     return NOERROR;
  88.     
  89. error: 
  90.     if (pCollection == NULL)
  91.         return E_OUTOFMEMORY;                       
  92.     if (pCollection->m_psa) 
  93.         SafeArrayDestroy(pCollection->m_psa); 
  94.   
  95.     pCollection->m_psa = NULL;
  96.     
  97.     delete pCollection;
  98.     return hr;
  99. }
  100.  
  101. /*
  102.  * CCollection::CCollection
  103.  *
  104.  * Purpose:
  105.  *  Constructor for CCollection object. Initializes members to NULL.
  106.  *
  107.  */
  108. CCollection::CCollection()
  109. {
  110.     m_psa = NULL;
  111. }
  112.  
  113. /*
  114.  * CCollection::~CCollection
  115.  *
  116.  * Purpose:
  117.  *  Destructor for CCollection object. 
  118.  *
  119.  */
  120. CCollection::~CCollection()
  121. {                  
  122.      if (m_psa) SafeArrayDestroy(m_psa);
  123. }
  124.  
  125. STDMETHODIMP_(REFCLSID)
  126. CCollection::GetInterfaceID()
  127. {
  128.     return IID_ICollection;
  129. }
  130.  
  131. /*
  132.  * CCollection::get_Count
  133.  *
  134.  * Purpose:
  135.  *  Returns number of items in collection.
  136.  *
  137.  */
  138. STDMETHODIMP_(long)     
  139. CCollection::get_Count(void)  
  140. {
  141.     return m_cElements;             
  142. }
  143.  
  144. /*
  145.  * CCollection::get_Item
  146.  *
  147.  * Purpose:
  148.  *  Retrieves item from collection, given an index.
  149.  *
  150.  * Parameters:   
  151.  *   lIndex   Index of item to be retrieved. 
  152.  *
  153.  * Returns
  154.  *  IDispatch of item retrieved from collection.
  155.  *
  156.  */
  157. STDMETHODIMP_(LPDISPATCH)
  158. CCollection::get_Item(long lIndex)
  159.     HRESULT hr;
  160.     VARIANT v;
  161.     LPDISPATCH pdisp = NULL;
  162.    
  163.     // Check if integer index is within range         
  164.     if (lIndex < m_lLBound || lIndex >= (long)(m_lLBound+m_cElements)) 
  165.         {RaiseException(IDS_InvalidIndex); return NULL;}
  166.     
  167.     // Retrieve and return item. Note that SafeArrayGetElement AddRefs so an additional AddRef
  168.     // is not required.
  169.     VariantInit(&v);
  170.     hr = SafeArrayGetElement(m_psa, &lIndex, &v);
  171.     if (FAILED(hr))
  172.         {RaiseException(IDS_Unexpected); return NULL;}
  173.     return V_DISPATCH(&v); 
  174. }
  175.  
  176. /*
  177.  * CCollection::get_NewEnum
  178.  *
  179.  * Purpose:
  180.  *  Returns an enumerator (IEnumVARIANT) for the items curently in the collection. 
  181.  *  The NewEnum property is restricted and so is invisible to users of an 
  182.  *  automation controller's scripting language. Automation controllers that support
  183.  *  a 'For Each' statement to iterate through the elements of a collection will use
  184.  *  the enumerator returned by NewEnum. The enumerator creates a snapshot of the
  185.  *  the current state of the collection.
  186.  *
  187.  */
  188. STDMETHODIMP_(LPUNKNOWN)
  189. CCollection::get__NewEnum(void)
  190. {
  191.     CEnumVariant FAR* penum = NULL;;
  192.     LPUNKNOWN punkEnumVariant = NULL;
  193.     HRESULT hr;
  194.  
  195.     // Create new enumerator for items currently in collection and QI for IUnknown
  196.     hr = CEnumVariant::Create(m_psa, m_cElements, &penum);
  197.     if (FAILED(hr))
  198.         {RaiseException(IDS_OutOfMemory); goto error;}       
  199.     hr = penum->QueryInterface(IID_IUnknown, (VOID FAR* FAR*)&punkEnumVariant);    
  200.     if (FAILED(hr)) 
  201.         {RaiseException(IDS_Unexpected); goto error;}         
  202.     return punkEnumVariant; 
  203.     
  204. error:
  205.     if (penum)
  206.         delete penum;    
  207.     return NULL;              
  208. }
  209.  
  210. /*
  211.  * CCollection::Add
  212.  *
  213.  * Purpose:
  214.  *  Adds an item to the collection. 
  215.  *
  216.  * Parameters:
  217.  *  pdispItemAdd    Item to be added to collection.
  218.  *
  219.  */
  220. STDMETHODIMP_(void)   
  221. CCollection::Add(LPDISPATCH pdispItem)
  222.     HRESULT hr;   
  223.     LONG l;
  224.     VARIANT v;  
  225.     
  226.     // Is the collection full?
  227.     if (m_cElements == m_cMax) 
  228.         {RaiseException(IDS_CollectionFull); return;}             
  229.        
  230.     l = m_lLBound+m_cElements;              
  231.     VariantInit(&v);
  232.     V_VT(&v) = VT_DISPATCH;
  233.     V_DISPATCH(&v) = pdispItem; 
  234.        
  235.     hr = SafeArrayPutElement(m_psa, &l, &v);
  236.     if (FAILED(hr))
  237.         {RaiseException(IDS_Unexpected); return;}               
  238.           
  239.     m_cElements++;                      
  240. }
  241.