📄 ccomcollect.cpp
字号:
// Snagged this code from http://www.widgetware.com/ATLFAQ_Collections.htm// The code came from Chris Brooks (clbrooks@micron.com)#include <vector>#include "CComCollect.h"/////////////////////////////////////////////////////////////////////////////// CComCollect// // icontainer: The interface for the container// container_iid: The IID for the container interface// libid: The GUID for the library// container: The implementation class for the container// icontained: The interface for the contained interface// contained_iid: The IID for the contained interface//// Usage:// Derive your collection class from this and CComObjectRootEx. Since this template class// inherits from CComCoClass, IDispatchImpl, and ISupportErrorInfo, you should not inherit// from those in your concrete class. Here's an example declaration://// class ATL_NO_VTABLE CSomeCollection : // public CComObjectRootEx<CComSingleThreadModel>,// public CComCollect<ISomeCollection, &IID_ISomeCollection,&LIBID_SomeLib, CSomeItem, // &CLSID_SomeCollection, ISomeInterface, &IID_ISomeInterface>//// If all you need are the standard Add, Remove, Item, get_Count, and get__NewEnum methods,// then you do not need to provide any other implementation. Just make sure you declare// the interface for your collection class in an IDL file. Here's the example for the// above declaration://// interface ISomeCollection : IDispatch// {// [propget, id(1)] HRESULT Count([out, retval] long *pVal);// [id(2)] HRESULT Add([in] ISPCChart* inItem);// [id(3)] HRESULT Remove([in] long inIndex);// [propget, id(DISPID_VALUE)] HRESULT Item([in] long inIndex,// [out, retval] ISPCChart** outChart);// [propget, id(DISPID_NEWENUM)] HRESULT _NewEnum([out, retval]LPUNKNOWN *pVal);// };//// You are free to add additional accessor/builder methods (note that the collection // implementation is exposed. Just declare it in your header and the IDL and provide an// implementation.//template <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID*contained_iid>class ATL_NO_VTABLE CComCollect : public CComCoClass<container, container_clsid>,public IDispatchImpl<icontainer, container_iid, libid>, public ISupportErrorInfo{public: CComCollect() {}// ISPCChartSpecspublic: STDMETHOD(RemoveAll)(); STDMETHOD(Add)(/*[in]*/ icontained* inItem); STDMETHOD(get__NewEnum)(/*[out, retval]*/ LPUNKNOWN *pVal); STDMETHOD(get_Item)(/*[in]*/ long inIndex, /*[out, retval]*/icontained** outChart); STDMETHOD(get_Count)(/*[out, retval]*/ long *pVal); STDMETHOD(Remove)(/*[in]*/ long inIndex); // ISupportsErrorInfo STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid); // Helper functions typedef std::vector<CComVariant> collection; typedef collection::iterator iterator; iterator begin(); iterator end(); protected: collection mCollect;};template <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>STDMETHODIMP CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid> ::InterfaceSupportsErrorInfo(REFIID riid){ static const IID* arr[] = { container_iid, }; for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE;}template <class icontainer, const IID* container_iid, const GUID* libid, class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::iterator CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::begin(){ return mCollect.begin();}template <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::iteratorCComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::end(){ return mCollect.end();}// Returns the number of elements in the collectiontemplate <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>STDMETHODIMP CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::get_Count(long * pVal){ // Make sure we didn't get a null pointer passed in if (!pVal) return E_POINTER; // Get the size from the collection *pVal = mCollect.size(); return S_OK;}// Returns a single item corresponding to the indextemplate <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>STDMETHODIMP CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::get_Item(long inIndex, icontained** outContained){ // Make sure we didn't get a null pointer passed in if (!outContained) return E_POINTER; // Make sure the index is within range (index is 1-based) if (inIndex < 1 || inIndex > mCollect.size()) return E_INVALIDARG; // Get the variant out of the collection CComVariant& var = mCollect[inIndex-1]; // Make sure we've got an element HRESULT hr = var.pdispVal->QueryInterface(*contained_iid, (void**)outContained); if (FAILED(hr)) return E_UNEXPECTED; return S_OK;}template <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>STDMETHODIMP CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::get__NewEnum(LPUNKNOWN * pVal){ // Make sure we didn't get a null pointer passed in if (!pVal) return E_POINTER; *pVal = 0; // Create the enumeration object typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > enumVar; enumVar* pEnum = new enumVar; if (!pEnum) return E_OUTOFMEMORY; // Initialize with the chart collection iterators HRESULT hr = pEnum->Init(mCollect.begin(), mCollect.end(), NULL,AtlFlagCopy); if (SUCCEEDED(hr)) hr = pEnum->QueryInterface(IID_IEnumVARIANT, (void**)pVal); if (FAILED(hr)) delete pEnum; return hr;}template <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>STDMETHODIMP CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::Add(icontained* inItem){ HRESULT hr = S_OK; icontained* pContained; // Make sure we've got an element hr = inItem->QueryInterface(*contained_iid, (void **)&pContained); if (FAILED(hr)) return E_UNEXPECTED; // Add the variant (dispatch) to the collection mDirty = TRUE; mCollect.push_back(CComVariant(inItem)); pContained->Release(); return hr;}// Removes an item at an integer index template <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>STDMETHODIMP CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::Remove(long inIndex){ HRESULT hr = S_OK; // Make sure the index is within range (index is 1-based) if (inIndex < 1 || inIndex > mCollect.size()) return E_INVALIDARG; mDirty = TRUE; mCollect.erase(mCollect.begin() + inIndex - 1); return hr;}///////////////////////////////////////////////////////////////// Remove all elements from the collection//template <class icontainer, const IID* container_iid, const GUID* libid,class container, const CLSID* container_clsid, class icontained, const IID* contained_iid>STDMETHODIMP CComCollect<icontainer, container_iid, libid, container, container_clsid, icontained, contained_iid>::RemoveAll(){ mCollect.erase(mCollect.begin(), mCollect.end()); return S_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -