home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 25: Programming / pc_actual_25.iso / C_C++ / BorlandCompiler / freecommandLinetools.exe / Include / mspcoll.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-27  |  10.1 KB  |  423 lines

  1. /*
  2.  
  3.     Copyright (c) 1998-1999  Microsoft Corporation
  4.  
  5. */
  6.  
  7. #ifndef _MSPCOLL_H_
  8. #pragma option push -b -a8 -pc -A- /*P_O_Push*/
  9. #define _MSPCOLL_H_
  10.  
  11.  
  12. ////////////////////////////////////////////////////////////////////////
  13. // CTapiIfCollection -- adapted from tapi3 code
  14. //      Collection template for collections of IDispatch interfaces
  15. //
  16. ////////////////////////////////////////////////////////////////////////
  17.  
  18. template <class T> class CTapiIfCollection :
  19.     public IDispatchImpl<ITCollection, &IID_ITCollection, &LIBID_TAPI3Lib>,
  20.     public CComObjectRootEx<CComMultiThreadModelNoCS>
  21. {
  22. public:
  23.     typedef CTapiIfCollection<T> _CTapiCollectionBase;
  24.     
  25. BEGIN_COM_MAP(_CTapiCollectionBase)
  26.     COM_INTERFACE_ENTRY(IDispatch)
  27.     COM_INTERFACE_ENTRY(ITCollection)
  28. END_COM_MAP()
  29.  
  30. private:
  31.  
  32.     int                 m_nSize;
  33.     CComVariant *       m_Var;
  34.     
  35. public:
  36.  
  37.     // ZoltanS: added constructor
  38.     CTapiIfCollection(void) : m_nSize(0), m_Var(NULL) { }
  39.  
  40.     // initialize
  41.     HRESULT STDMETHODCALLTYPE Initialize(
  42.                                          DWORD dwSize,
  43.                                          T * pBegin,
  44.                                          T * pEnd                                         
  45.                                         )
  46.     {
  47.         int                     i;
  48.         HRESULT                 hr;
  49.         T *                     iter;
  50.  
  51.         LOG((MSP_TRACE, "CTapiCollection::Initialize - enter"));
  52.  
  53.         // create variant array
  54.         m_nSize = dwSize;
  55.  
  56.         m_Var = new CComVariant[m_nSize];
  57.         if (m_Var == NULL)
  58.         {
  59.             // debug output
  60.             return E_OUTOFMEMORY;
  61.         }
  62.  
  63.         i = 0;
  64.  
  65.         for (iter = pBegin; iter != pEnd; iter++)
  66.         {
  67.             // get IDispatch pointer
  68.             IDispatch * pDisp = NULL;
  69.  
  70.             hr = (*iter)->QueryInterface(IID_IDispatch, (void**)&pDisp);
  71.  
  72.             if (hr != S_OK)
  73.             {
  74.                 return hr;
  75.             }
  76.  
  77.             // create a variant and add it to the collection
  78.             CComVariant& var = m_Var[i];
  79.  
  80.             VariantInit(&var);
  81.             
  82.             var.vt = VT_DISPATCH;
  83.             var.pdispVal = pDisp;
  84.  
  85.             i++;
  86.         }
  87.  
  88.         LOG((MSP_TRACE, "CTapiCollection::Initialize - exit"));
  89.         
  90.         return S_OK;
  91.     }
  92.  
  93.     void FinalRelease()
  94.     {
  95.         LOG((MSP_TRACE, "CTapiCollection::FinalRelease - enter"));
  96.  
  97.         //
  98.         // We "new"ed an array of objects. Delete each object in the array. The
  99.         // destructor for each object calls VariantClear to release the pointer
  100.         // in that object, based on the variant's tag.
  101.         //
  102.  
  103.         delete [] m_Var;
  104.  
  105.         LOG((MSP_TRACE, "CTapiCollection::FinalRelease - exit"));
  106.     }
  107.     
  108.     STDMETHOD(get_Count)(
  109.                          long* retval
  110.                         )
  111.     {
  112.         HRESULT         hr = S_OK;
  113.         
  114.         LOG((MSP_TRACE, "CTapiCollection::get_Count - enter"));
  115.         
  116.         try
  117.         {
  118.             *retval = m_nSize;
  119.         }
  120.         catch(...)
  121.         {
  122.             hr = E_INVALIDARG;
  123.         }
  124.  
  125.         LOG((MSP_TRACE, "CTapiCollection::get_Count - exit"));
  126.  
  127.         return hr;
  128.     }
  129.  
  130.     STDMETHOD(get_Item)(
  131.                                        long Index, 
  132.                                        VARIANT* retval
  133.                                       )
  134.     {
  135.         HRESULT         hr = S_OK;
  136.  
  137.         LOG((MSP_TRACE, "CTapiCollection::get_Item - enter"));
  138.         
  139.         if (retval == NULL)
  140.         {
  141.             return E_POINTER;
  142.         }
  143.  
  144.         try
  145.         {
  146.             VariantInit(retval);
  147.         }
  148.         catch(...)
  149.         {
  150.             hr = E_INVALIDARG;
  151.         }
  152.  
  153.         if (hr != S_OK)
  154.         {
  155.             return hr;
  156.         }
  157.  
  158.         retval->vt = VT_UNKNOWN;
  159.         retval->punkVal = NULL;
  160.  
  161.         // use 1-based index, VB like
  162.         if ((Index < 1) || (Index > m_nSize))
  163.         {
  164.             return E_INVALIDARG;
  165.         }
  166.  
  167.         VariantCopy(retval, &m_Var[Index-1]);
  168.  
  169.         LOG((MSP_TRACE, "CTapiCollection::get_Item - exit"));
  170.         
  171.         return S_OK;
  172.     }
  173.  
  174.     HRESULT STDMETHODCALLTYPE get__NewEnum(
  175.                                            IUnknown** retval
  176.                                           )
  177.     
  178.     {
  179.         HRESULT         hr;
  180.  
  181.         LOG((MSP_TRACE, "CTapiCollection::new__Enum - enter"));
  182.         
  183.         if (retval == NULL)
  184.         {
  185.             return E_POINTER;
  186.         }
  187.  
  188.         *retval = NULL;
  189.  
  190.         typedef CComObject<CSafeComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > enumvar;
  191.  
  192.         enumvar* p; // = new enumvar;
  193.         hr = enumvar::CreateInstance( &p );
  194.  
  195.         if ( FAILED(hr) )
  196.         {
  197.             // debug output
  198.             return hr;
  199.         }
  200.  
  201.         hr = p->Init(&m_Var[0], &m_Var[m_nSize], NULL, AtlFlagCopy);
  202.  
  203.         if (SUCCEEDED(hr))
  204.         {
  205.             hr = p->QueryInterface(IID_IEnumVARIANT, (void**)retval);
  206.         }
  207.  
  208.         if (FAILED(hr))
  209.         {
  210.             delete p;
  211.         }
  212.  
  213.         LOG((MSP_TRACE, "CTapiCollection::new__Enum - exit"));
  214.         
  215.         return hr;
  216.  
  217.     }
  218. };
  219.  
  220. ////////////////////////////////////////////////////////////////////////
  221. // CTapiBstrCollection -- adapted from tapi3 code
  222. //    Collection of BSTRs.
  223. ////////////////////////////////////////////////////////////////////////
  224. class CTapiBstrCollection :
  225.     public CComObjectRootEx<CComMultiThreadModelNoCS>,
  226.     public IDispatchImpl<ITCollection, &IID_ITCollection, &LIBID_TAPI3Lib>
  227. {
  228. public:
  229.     
  230. BEGIN_COM_MAP(CTapiBstrCollection)
  231.     COM_INTERFACE_ENTRY(IDispatch)
  232.     COM_INTERFACE_ENTRY(ITCollection)
  233. END_COM_MAP()
  234.  
  235. private:
  236.  
  237.     DWORD               m_dwSize;
  238.     CComVariant *       m_Var;
  239.     
  240. public:
  241.  
  242.     // ZoltanS: added constructor
  243.     CTapiBstrCollection(void) : m_dwSize(0), m_Var(NULL) { }
  244.  
  245.     // initialize
  246.     HRESULT STDMETHODCALLTYPE Initialize(
  247.                                          DWORD dwSize,
  248.                                          BSTR * pBegin,
  249.                                          BSTR * pEnd                                         
  250.                                         )
  251.     {
  252.         BSTR *  i;
  253.         DWORD   dw = 0;
  254.  
  255.         LOG((MSP_TRACE, "CTapiBstrCollection::Initialize - enter"));
  256.  
  257.         // create variant array
  258.         m_dwSize = dwSize;
  259.  
  260.         m_Var = new CComVariant[m_dwSize];
  261.  
  262.         if (m_Var == NULL)
  263.         {
  264.             // debug output
  265.             return E_OUTOFMEMORY;
  266.         }
  267.  
  268.         for (i = pBegin; i != pEnd; i++)
  269.         {
  270.             // create a variant and add it to the collection
  271.             CComVariant& var = m_Var[dw];
  272.  
  273.             var.vt = VT_BSTR;
  274.             var.bstrVal = *i;
  275.  
  276.             dw++;
  277.         }
  278.  
  279.         LOG((MSP_TRACE, "CTapiBstrCollection::Initialize - exit"));
  280.         
  281.         return S_OK;
  282.     }
  283.     
  284.     STDMETHOD(get_Count)(
  285.                          long* retval
  286.                         )
  287.     {
  288.         HRESULT         hr = S_OK;
  289.  
  290.         LOG((MSP_TRACE, "CTapiBstrCollection::get_Count - enter"));        
  291.  
  292.         try
  293.         {
  294.             *retval = m_dwSize;
  295.         }
  296.         catch(...)
  297.         {
  298.             hr = E_INVALIDARG;
  299.         }
  300.  
  301.         LOG((MSP_TRACE, "CTapiBstrCollection::get_Count - exit"));
  302.         
  303.         return hr;
  304.     }
  305.  
  306.     STDMETHOD(get_Item)(
  307.                         long Index, 
  308.                         VARIANT* retval
  309.                        )
  310.     {
  311.         HRESULT         hr = S_OK;
  312.  
  313.         LOG((MSP_TRACE, "CTapiBstrCollection::get_Item - enter"));
  314.         
  315.         if (retval == NULL)
  316.         {
  317.             return E_POINTER;
  318.         }
  319.  
  320.         try
  321.         {
  322.             VariantInit(retval);
  323.         }
  324.         catch(...)
  325.         {
  326.             hr = E_INVALIDARG;
  327.         }
  328.  
  329.         if (hr != S_OK)
  330.         {
  331.             return hr;
  332.         }
  333.  
  334.         retval->vt = VT_BSTR;
  335.         retval->bstrVal = NULL;
  336.  
  337.         // use 1-based index, VB like
  338.         // ZoltanS: no problem with signed/unsigned, since
  339.         // if Index < 0 then first clause is true, making it
  340.         // irrelevant if the second clause is correct or not.
  341.  
  342.         if ((Index < 1) || ( (DWORD) Index > m_dwSize))
  343.         {
  344.             return E_INVALIDARG;
  345.         }
  346.  
  347.         //
  348.         // This copies the string, not just the pointer.
  349.         //
  350.  
  351.         VariantCopy(retval, &m_Var[Index-1]);
  352.  
  353.         LOG((MSP_TRACE, "CTapiBstrCollection::get_Item - exit"));
  354.  
  355.         return S_OK;
  356.     }
  357.  
  358.     HRESULT STDMETHODCALLTYPE get__NewEnum(
  359.                                            IUnknown** retval
  360.                                           )
  361.     
  362.     {
  363.         HRESULT         hr;
  364.  
  365.         LOG((MSP_TRACE, "CTapiBstrCollection::get__NumEnum - enter"));
  366.         
  367.         if (retval == NULL)
  368.         {
  369.             return E_POINTER;
  370.         }
  371.  
  372.         *retval = NULL;
  373.  
  374.         typedef CComObject<CSafeComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > enumvar;
  375.  
  376.         enumvar* p = new enumvar;
  377.  
  378.         if ( p == NULL)
  379.         {
  380.             // debug output
  381.             return E_OUTOFMEMORY;
  382.         }
  383.  
  384.         hr = p->Init(&m_Var[0], &m_Var[m_dwSize], NULL, AtlFlagCopy);
  385.  
  386.         if (SUCCEEDED(hr))
  387.         {
  388.             hr = p->QueryInterface(IID_IEnumVARIANT, (void**)retval);
  389.         }
  390.  
  391.         if (FAILED(hr))
  392.         {
  393.             delete p;
  394.         }
  395.  
  396.         LOG((MSP_TRACE, "CTapiBstrCollection::get__NewEnum - exit"));
  397.         
  398.         return hr;
  399.  
  400.     }
  401.  
  402.     void FinalRelease()
  403.     {
  404.         LOG((MSP_TRACE, "CTapiBstrCollection::FinalRelease() - enter"));
  405.  
  406.         //
  407.         // We "new"ed an array of objects. Delete each object in the array. The
  408.         // destructor for each object calls VariantClear to release the pointer
  409.         // in that object, based on the variant's tag.
  410.         //
  411.  
  412.         delete [] m_Var;
  413.  
  414.         LOG((MSP_TRACE, "CTapiBstrCollection::FinalRelease() - exit"));
  415.     }
  416.  
  417. };
  418.  
  419. #pragma option pop /*P_O_Pop*/
  420. #endif // _MSPCOLL_H_
  421.  
  422. // eof
  423.