|
#pragma once
template <typename T>
struct _CopyVariantFromAdaptItf
{
static HRESULT copy(VARIANT * p1, const CAdapt< CComPtr<T> > * p2)
{
HRESULT hr = p2->m_T->QueryInterface(IID_IDispatch, (void**)&p1->pdispVal);
if(SUCCEEDED(hr))
p1->vt = VT_DISPATCH;
return hr;
}
static void init(VARIANT * p)
{
::VariantInit(p);
}
static void destroy(VARIANT * p)
{
::VariantClear(p);
}
};
template <typename T>
struct _CopyItfFromAdaptItf
{
static HRESULT copy(T ** p1, const CAdapt< CComPtr<T> > * p2)
{
if(*p1 = p2->m_T)
{
(*p1)->AddRef();
return S_OK;
}
return E_POINTER;
}
static void init(T ** p){};
static void destroy(T ** p)
{
if(*p)
(*p)->Release();
}
};
template <class T, class CollType, class ItemType, class CopyItem, class EnumType>
class ISafeCollectionOnSTLImpl : public T
{
public:
ISafeCollectionOnSTLImpl()
{
::InitializeCriticalSection(&m_csCollection);
}
~ISafeCollectionOnSTLImpl()
{
::DeleteCriticalSection(&m_csCollection);
}
STDMETHOD(get_Count)(long* pcount)
{
HRESULT hr = OnInterfaceAccess();
if(hr != S_OK)
return hr;
CCritSecLock cs(m_csCollection);
if (pcount == NULL)
return E_POINTER;
ATLASSUME(m_coll.size() <= LONG_MAX);
*pcount = (long)m_coll.size();
return S_OK;
}
STDMETHOD(get_Item)(long Index, ItemType* pvar)
{
HRESULT hr = OnInterfaceAccess();
if(hr != S_OK)
return hr;
CCritSecLock cs(m_csCollection);
if(Index < 1 || Index > (long)m_coll.size())
return OnIndexOutOfRange();
//Index is 1-based;
if (pvar == NULL)
return E_POINTER;
hr = E_FAIL;
Index--;
CollType::const_iterator iter = m_coll.begin();
while (iter != m_coll.end() && Index > 0)
{
iter++;
Index--;
}
if (iter != m_coll.end())
hr = CopyItem::copy(pvar, &*iter);
return hr;
}
STDMETHOD(get__NewEnum)(IUnknown** ppUnk)
{
HRESULT hr = OnInterfaceAccess();
if(hr != S_OK)
return hr;
CCritSecLock cs(m_csCollection);
if (ppUnk == NULL)
return E_POINTER;
*ppUnk = NULL;
CComObject<EnumType>* p;
hr = CComObject<EnumType>::CreateInstance(&p);
if (SUCCEEDED(hr))
{
hr = p->Init(this, m_coll);
if(hr == S_OK)
hr = p->QueryInterface(__uuidof(IUnknown), (void**)ppUnk);
}
if (hr != S_OK)
delete p;
return hr;
}
CollType m_coll;
CRITICAL_SECTION m_csCollection;
protected:
virtual HRESULT OnIndexOutOfRange(){return E_INVALIDARG;};
virtual HRESULT OnInterfaceAccess(){return S_OK;}; // Notifies about access to the interface properties or methods;
};
#define DECLARE_PSL_COLLECTION(Col, T)\
typedef vector<CAdapt<CComPtr<IPSL##T> > > Col##Type;\
typedef CComEnumOnSTL<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _CopyVariantFromAdaptItf<IPSL##T>, Col##Type, CComGlobalsThreadModel > C##T##EnumImpl;\
typedef ISafeCollectionOnSTLImpl<IDispatchImpl<IPSL##Col, &IID_IPSL##Col, &LIBID_ProSysLib, PSL_HiVersion, PSL_LoVersion>, Col##Type, IPSL##T*, _CopyItfFromAdaptItf<IPSL##T>, C##T##EnumImpl> C##Col##Collection;
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.