--- /dev/null
+#pragma once
+
+#include <atlbase.h>
+#include <atlcom.h>
+
+// \92l\82ð\83R\83s\81[\82·\82é\83o\83\8a\83A\83\93\83g\97ñ\8b\93\8c^
+typedef CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > CComEnumVARIANT;
+
+// \93®\93I\82È\83o\83\8a\83A\83\93\83g\97ñ\8b\93\8c^
+template <class T>
+class CComEnumDynaVARIANT :public IEnumVARIANT, public CComObjectRootEx<CComSingleThreadModel>
+{
+public:
+ BEGIN_COM_MAP(CComEnumDynaVARIANT)
+ COM_INTERFACE_ENTRY(IEnumVARIANT)
+ COM_INTERFACE_ENTRY(IUnknown)
+ END_COM_MAP()
+
+ CComEnumDynaVARIANT()
+ {
+ m_current = 0;
+ m_pObj = NULL;
+ }
+ STDMETHODIMP Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched);
+ STDMETHODIMP Skip(unsigned long celt);
+ STDMETHODIMP Reset();
+ STDMETHODIMP Clone(IEnumVARIANT FAR* FAR* ppenum);
+ void FinalRelease()
+ {
+ if (m_pObj) {
+ m_pObj->Release();
+ m_pObj = NULL;
+ }
+ ATLTRACE("CComEnumDynaVARINAT::FinalRelease\r\n");
+ }
+ void Init(T* pObj, unsigned long current)
+ {
+ m_current = current;
+ m_pObj = pObj;
+ if (m_pObj) {
+ m_pObj->AddRef();
+ }
+ }
+protected:
+ unsigned long m_current;
+ T* m_pObj;
+};
+
+template<class T>
+STDMETHODIMP CComEnumDynaVARIANT<T>::Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched)
+{
+ // \96ß\82·\94z\97ñ\82Ì\92l\82ð\8f\89\8aú\89»
+ if (!m_pObj) {
+ return S_FALSE;
+ }
+
+ for (unsigned long i = 0; i < celt; i++) {
+ ::VariantInit(&rgvar[i]);
+ }
+
+ unsigned long cnt = 0;
+ unsigned long mx = 0;
+ m_pObj->get_Count((long*)&mx);
+ while (cnt < celt && m_current < mx) {
+ CComVariant varIdx((long)m_current);
+ m_pObj->get_Value(varIdx, &rgvar[cnt]);
+ m_current++;
+ celt--;
+ cnt++;
+ }
+
+ // \8eÀ\8dÛ\82É\8f\91\82«\96ß\82µ\82½\92l\82ð\8f\89\8aú\89»\82·\82é
+ if (pceltFetched) {
+ *pceltFetched = cnt;
+ }
+ return (celt > cnt) ? S_FALSE : S_OK;
+}
+
+template<class T>
+STDMETHODIMP CComEnumDynaVARIANT<T>::Skip(unsigned long celt)
+{
+ if (m_pObj) {
+ unsigned long mx = 0;
+ m_pObj->get_Count((long*)&mx);
+ if (m_current + celt < mx) {
+ m_current += celt;
+ return S_OK;
+ }
+ }
+ return S_FALSE;
+}
+
+template<class T>
+STDMETHODIMP CComEnumDynaVARIANT<T>::Reset()
+{
+ m_current = 0;
+ return S_OK;
+}
+
+template<class T>
+STDMETHODIMP CComEnumDynaVARIANT<T>::Clone(IEnumVARIANT FAR* FAR* ppenum)
+{
+ CComObject< CComEnumDynaVARIANT<T> >* pClone = NULL;
+ pClone->CreateInstance(&pClone);
+ pClone->Init(m_pObj, m_current);
+ pClone->QueryInterface(IID_IEnumVARIANT, (void**)ppenum);
+ return S_OK;
+}