| /** |
| * This file has no copyright assigned and is placed in the Public Domain. |
| * This file is part of the mingw-w64 runtime package. |
| * No warranty is given; refer to the file DISCLAIMER.PD within this package. |
| */ |
| #ifndef _MSPCOLL_H_ |
| #define _MSPCOLL_H_ |
| |
| template <class T> class CTapiIfCollection : public IDispatchImpl<ITCollection,&IID_ITCollection,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModelNoCS> |
| { |
| public: |
| typedef CTapiIfCollection<T> _CTapiCollectionBase; |
| BEGIN_COM_MAP(_CTapiCollectionBase) |
| COM_INTERFACE_ENTRY(IDispatch) |
| COM_INTERFACE_ENTRY(ITCollection) |
| END_COM_MAP() |
| private: |
| int m_nSize; |
| CComVariant *m_Var; |
| |
| public: |
| CTapiIfCollection(void) : m_nSize(0),m_Var(NULL) { } |
| HRESULT WINAPI Initialize(DWORD dwSize,T *pBegin,T *pEnd) { |
| int i; |
| HRESULT hr; |
| T *iter; |
| LOG((MSP_TRACE,"CTapiCollection::Initialize - enter")); |
| m_nSize = dwSize; |
| m_Var = new CComVariant[m_nSize]; |
| if(!m_Var) return E_OUTOFMEMORY; |
| i = 0; |
| for(iter = pBegin;iter!=pEnd;iter++) { |
| IDispatch *pDisp = NULL; |
| hr = (*iter)->QueryInterface(IID_IDispatch,(void**)&pDisp); |
| if(hr!=S_OK) return hr; |
| CComVariant& var = m_Var[i]; |
| VariantInit(&var); |
| var.vt = VT_DISPATCH; |
| var.pdispVal = pDisp; |
| i++; |
| } |
| LOG((MSP_TRACE,"CTapiCollection::Initialize - exit")); |
| return S_OK; |
| } |
| void FinalRelease() { |
| LOG((MSP_TRACE,"CTapiCollection::FinalRelease - enter")); |
| delete [] m_Var; |
| LOG((MSP_TRACE,"CTapiCollection::FinalRelease - exit")); |
| } |
| STDMETHOD(get_Count)(__LONG32 *retval) { |
| HRESULT hr = S_OK; |
| LOG((MSP_TRACE,"CTapiCollection::get_Count - enter")); |
| try { |
| *retval = m_nSize; |
| } catch(...) { |
| hr = E_INVALIDARG; |
| } |
| LOG((MSP_TRACE,"CTapiCollection::get_Count - exit")); |
| return hr; |
| } |
| STDMETHOD(get_Item)(__LONG32 Index,VARIANT *retval) { |
| HRESULT hr = S_OK; |
| LOG((MSP_TRACE,"CTapiCollection::get_Item - enter")); |
| if(!retval) return E_POINTER; |
| try { |
| VariantInit(retval); |
| } catch(...) { |
| hr = E_INVALIDARG; |
| } |
| if(hr!=S_OK) return hr; |
| retval->vt = VT_UNKNOWN; |
| retval->punkVal = NULL; |
| if((Index < 1) || (Index > m_nSize)) return E_INVALIDARG; |
| hr = VariantCopy(retval,&m_Var[Index-1]); |
| if(FAILED(hr)) { |
| LOG((MSP_ERROR,"CTapiCollection::get_Item - VariantCopy failed. hr = %lx",hr)); |
| return hr; |
| } |
| LOG((MSP_TRACE,"CTapiCollection::get_Item - exit")); |
| return S_OK; |
| } |
| HRESULT WINAPI get__NewEnum(IUnknown **retval) { |
| HRESULT hr; |
| LOG((MSP_TRACE,"CTapiCollection::new__Enum - enter")); |
| if(!retval) return E_POINTER; |
| *retval = NULL; |
| typedef CComObject<CSafeComEnum<IEnumVARIANT,&IID_IEnumVARIANT,VARIANT,_Copy<VARIANT> > > enumvar; |
| enumvar *p; |
| hr = enumvar::CreateInstance(&p); |
| if(FAILED(hr)) return hr; |
| hr = p->Init(&m_Var[0],&m_Var[m_nSize],NULL,AtlFlagCopy); |
| if(SUCCEEDED(hr)) hr = p->QueryInterface(IID_IEnumVARIANT,(void**)retval); |
| if(FAILED(hr)) delete p; |
| LOG((MSP_TRACE,"CTapiCollection::new__Enum - exit")); |
| return hr; |
| } |
| }; |
| |
| class CTapiBstrCollection : public CComObjectRootEx<CComMultiThreadModelNoCS>,public IDispatchImpl<ITCollection,&IID_ITCollection,&LIBID_TAPI3Lib>,public CMSPObjectSafetyImpl |
| { |
| public: |
| BEGIN_COM_MAP(CTapiBstrCollection) |
| COM_INTERFACE_ENTRY(IDispatch) |
| COM_INTERFACE_ENTRY(ITCollection) |
| COM_INTERFACE_ENTRY(IObjectSafety) |
| END_COM_MAP() |
| private: |
| DWORD m_dwSize; |
| CComVariant *m_Var; |
| public: |
| CTapiBstrCollection(void) : m_dwSize(0),m_Var(NULL) { } |
| HRESULT WINAPI Initialize(DWORD dwSize,BSTR *pBegin,BSTR *pEnd) { |
| BSTR *i; |
| DWORD dw = 0; |
| LOG((MSP_TRACE,"CTapiBstrCollection::Initialize - enter")); |
| m_dwSize = dwSize; |
| m_Var = new CComVariant[m_dwSize]; |
| if(!m_Var) return E_OUTOFMEMORY; |
| for(i = pBegin;i!=pEnd;i++) { |
| CComVariant& var = m_Var[dw]; |
| var.vt = VT_BSTR; |
| var.bstrVal = *i; |
| dw++; |
| } |
| LOG((MSP_TRACE,"CTapiBstrCollection::Initialize - exit")); |
| return S_OK; |
| } |
| STDMETHOD(get_Count)(__LONG32 *retval) { |
| HRESULT hr = S_OK; |
| LOG((MSP_TRACE,"CTapiBstrCollection::get_Count - enter")); |
| try { |
| *retval = m_dwSize; |
| } catch(...) { |
| hr = E_INVALIDARG; |
| } |
| LOG((MSP_TRACE,"CTapiBstrCollection::get_Count - exit")); |
| return hr; |
| } |
| STDMETHOD(get_Item)(__LONG32 Index,VARIANT *retval) { |
| HRESULT hr = S_OK; |
| LOG((MSP_TRACE,"CTapiBstrCollection::get_Item - enter")); |
| if(!retval) return E_POINTER; |
| try { |
| VariantInit(retval); |
| } catch(...) { |
| hr = E_INVALIDARG; |
| } |
| if(hr!=S_OK) return hr; |
| retval->vt = VT_BSTR; |
| retval->bstrVal = NULL; |
| if((Index < 1) || ((DWORD) Index > m_dwSize)) return E_INVALIDARG; |
| hr = VariantCopy(retval,&m_Var[Index-1]); |
| if(FAILED(hr)) { |
| LOG((MSP_ERROR,"CTapiBstrCollection::get_Item - VariantCopy failed. hr = %lx",hr)); |
| return hr; |
| } |
| LOG((MSP_TRACE,"CTapiBstrCollection::get_Item - exit")); |
| return S_OK; |
| } |
| HRESULT WINAPI get__NewEnum(IUnknown **retval) { |
| HRESULT hr; |
| LOG((MSP_TRACE,"CTapiBstrCollection::get__NumEnum - enter")); |
| if(!retval) return E_POINTER; |
| *retval = NULL; |
| typedef CComObject<CSafeComEnum<IEnumVARIANT,&IID_IEnumVARIANT,VARIANT,_Copy<VARIANT> > > enumvar; |
| enumvar *p = new enumvar; |
| if(!p) return E_OUTOFMEMORY; |
| hr = p->Init(&m_Var[0],&m_Var[m_dwSize],NULL,AtlFlagCopy); |
| if(SUCCEEDED(hr)) { |
| hr = p->QueryInterface(IID_IEnumVARIANT,(void**)retval); |
| } |
| if(FAILED(hr)) delete p; |
| LOG((MSP_TRACE,"CTapiBstrCollection::get__NewEnum - exit")); |
| return hr; |
| } |
| void FinalRelease() { |
| LOG((MSP_TRACE,"CTapiBstrCollection::FinalRelease() - enter")); |
| delete [] m_Var; |
| LOG((MSP_TRACE,"CTapiBstrCollection::FinalRelease() - exit")); |
| } |
| }; |
| #endif |