Mspcoll.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:10k
源码类别:

模拟服务器

开发平台:

C/C++

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