ENUMVAR.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:
Windows编程
开发平台:
Visual C++
- // enumvar.cpp : implementation file
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #include "inproc.h"
- #include "enumvar.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CEnumVariant
- IMPLEMENT_DYNCREATE(CEnumVariant, CCmdTarget)
- CEnumVariant::CEnumVariant()
- {
- m_nIndex = 0;
- m_nCount = 0;
- m_pContents = NULL;
- m_pClonedFrom = NULL;
- // To keep the application running as long as an OLE automation
- // object is active, the constructor calls AfxOleLockApp.
- AfxOleLockApp();
- }
- CEnumVariant::~CEnumVariant()
- {
- if (m_pClonedFrom != NULL)
- {
- m_pClonedFrom->ExternalRelease();
- }
- else
- {
- for (int i = 0; i < m_nCount; ++i)
- VariantClear(&m_pContents[i]);
- delete[] m_pContents;
- }
- // To terminate the application when all objects created with
- // with OLE automation, the destructor calls AfxOleUnlockApp.
- AfxOleUnlockApp();
- }
- void CEnumVariant::OnFinalRelease()
- {
- // When the last reference for an automation object is released
- // OnFinalRelease is called. This implementation deletes the
- // object. Add additional cleanup required for your object before
- // deleting it from memory.
- delete this;
- }
- void CEnumVariant::SetContents(VARIANT* pContents, int nCount, int nIndex)
- {
- ASSERT(nIndex < nCount);
- ASSERT(nCount == 0 || pContents != NULL);
- ASSERT(pContents == NULL ||
- AfxIsValidAddress(pContents, sizeof(VARIANT)*nCount, FALSE));
- m_nCount = nCount;
- m_pContents = pContents;
- m_nIndex = nIndex;
- }
- BEGIN_MESSAGE_MAP(CEnumVariant, CCmdTarget)
- //{{AFX_MSG_MAP(CEnumVariant)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CEnumVariant interfaces
- static void CopyVariantArray(VARIANT* pDest, VARIANT* pSrc, int nCount)
- {
- for (int i = 0; i < nCount; ++i)
- VariantInit(&pDest[i]);
- for (i = 0; i < nCount; ++i)
- {
- SCODE sc = GetScode(VariantCopy(&pDest[i], &pSrc[i]));
- if (sc != NOERROR)
- {
- while (--i >= 0)
- VariantClear(&pDest[i]);
- AfxThrowMemoryException();
- }
- }
- }
- BEGIN_INTERFACE_MAP(CEnumVariant, CCmdTarget)
- INTERFACE_PART(CEnumVariant, IID_IEnumVARIANT, EnumVARIANT)
- END_INTERFACE_MAP()
- STDMETHODIMP_(ULONG) CEnumVariant::XEnumVARIANT::AddRef()
- {
- METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
- return pThis->ExternalAddRef();
- }
- STDMETHODIMP_(ULONG) CEnumVariant::XEnumVARIANT::Release()
- {
- METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
- return pThis->ExternalRelease();
- }
- STDMETHODIMP CEnumVariant::XEnumVARIANT::QueryInterface(REFIID iid, void** ppvObj)
- {
- METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
- return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj) ;
- }
- STDMETHODIMP CEnumVariant::XEnumVARIANT::Next(ULONG celt, VARIANT* rgvar, ULONG* pceltFetched)
- {
- METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
- ASSERT(celt > 0);
- ASSERT(celt == 1 || pceltFetched != NULL);
- if (pceltFetched != NULL)
- *pceltFetched = 0;
- int nFetched = min(pThis->m_nCount - pThis->m_nIndex, (int)celt);
- TRY
- {
- CopyVariantArray(rgvar, pThis->m_pContents + pThis->m_nIndex, nFetched);
- }
- CATCH_ALL(e)
- {
- return E_OUTOFMEMORY;
- }
- END_CATCH_ALL
- pThis->m_nIndex += nFetched;
- if (pceltFetched != NULL)
- *pceltFetched = nFetched;
- return nFetched == (int)celt ? NOERROR : S_FALSE;
- }
- STDMETHODIMP CEnumVariant::XEnumVARIANT::Skip(unsigned long celt)
- {
- METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
- int nSkip = (int)celt;
- if (nSkip + pThis->m_nIndex > pThis->m_nCount)
- nSkip = pThis->m_nCount - pThis->m_nIndex;
- pThis->m_nIndex += nSkip;
- return nSkip == (int)celt ? NOERROR : S_FALSE;
- }
- STDMETHODIMP CEnumVariant::XEnumVARIANT::Reset()
- {
- METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
- pThis->m_nIndex = 0;
- return NOERROR;
- }
- STDMETHODIMP CEnumVariant::XEnumVARIANT::Clone(IEnumVARIANT** ppenum)
- {
- METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
- CEnumVariant* pClone;
- TRY
- {
- pClone = new CEnumVariant;
- pClone->SetContents(pThis->m_pContents, pThis->m_nCount, pThis->m_nIndex);
- pClone->m_pClonedFrom = pThis;
- pThis->ExternalAddRef();
- }
- CATCH_ALL(e)
- {
- return E_OUTOFMEMORY;
- }
- END_CATCH_ALL
- *ppenum = &pClone->m_xEnumVARIANT;
- return NOERROR;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CEnumVariant message handlers