ENUMVAR.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:
Windows编程
开发平台:
Visual C++
- /*************************************************************************
- **
- ** This is a part of the Microsoft Source Code Samples.
- **
- ** Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
- **
- ** This source code is only intended as a supplement to Microsoft Development
- ** Tools and/or WinHelp documentation. See these sources for detailed
- ** information regarding the Microsoft samples programs.
- **
- ** OLE Automation TypeLibrary Browse Helper Sample
- **
- ** enumvar.cpp
- **
- ** CEnumVariant implementation
- **
- ** Written by Microsoft Product Support Services, Windows Developer Support
- **
- *************************************************************************/
- #include <windows.h>
- #include <windowsx.h>
- #ifdef WIN16
- #include <ole2.h>
- #include <compobj.h>
- #include <dispatch.h>
- #include <variant.h>
- #include <olenls.h>
- #endif
- #include "browseh.h"
- /*
- * CEnumVariant::Create
- *
- * Purpose:
- * Creates an instance of the IEnumVARIANT enumerator object and initializes it.
- *
- * Parameters:
- * psa Safe array containing items to be enumerated.
- * cElements Number of items to be enumerated.
- * ppenumvariant Returns enumerator object.
- *
- * Return Value:
- * HRESULT
- *
- */
- HRESULT
- CEnumVariant::Create(SAFEARRAY FAR* psa, ULONG cElements, CEnumVariant FAR* FAR* ppenumvariant)
- {
- HRESULT hr;
- CEnumVariant FAR* penumvariant = NULL;
- long lLBound;
- *ppenumvariant = NULL;
- penumvariant = new CEnumVariant();
- if (penumvariant == NULL)
- goto error;
- penumvariant->m_cRef = 0;
- // Copy elements into safe array that is used in enumerator implemenatation and
- // initialize state of enumerator.
- hr = SafeArrayGetLBound(psa, 1, &lLBound);
- if (FAILED(hr))
- goto error;
- penumvariant->m_cElements = cElements;
- penumvariant->m_lLBound = lLBound;
- penumvariant->m_lCurrent = lLBound;
- hr = SafeArrayCopy(psa, &penumvariant->m_psa);
- if (FAILED(hr))
- goto error;
- *ppenumvariant = penumvariant;
- return NOERROR;
- error:
- if (penumvariant == NULL)
- return E_OUTOFMEMORY;
- if (penumvariant->m_psa)
- SafeArrayDestroy(penumvariant->m_psa);
- penumvariant->m_psa = NULL;
- delete penumvariant;
- return hr;
- }
- /*
- * CEnumVariant::CEnumVariant
- *
- * Purpose:
- * Constructor for CEnumVariant object. Initializes members to NULL.
- *
- */
- CEnumVariant::CEnumVariant()
- {
- m_psa = NULL;
- }
- /*
- * CEnumVariant::~CEnumVariant
- *
- * Purpose:
- * Destructor for CEnumVariant object.
- *
- */
- CEnumVariant::~CEnumVariant()
- {
- if (m_psa) SafeArrayDestroy(m_psa);
- }
- /*
- * CEnumVariant::QueryInterface, AddRef, Release
- *
- * Purpose:
- * Implements IUnknown::QueryInterface, AddRef, Release
- *
- */
- STDMETHODIMP
- CEnumVariant::QueryInterface(REFIID iid, void FAR* FAR* ppv)
- {
- *ppv = NULL;
- if (iid == IID_IUnknown || iid == IID_IEnumVARIANT)
- *ppv = this;
- else return E_NOINTERFACE;
- AddRef();
- return NOERROR;
- }
- STDMETHODIMP_(ULONG)
- CEnumVariant::AddRef(void)
- {
- #ifdef _DEBUG
- TCHAR ach[50];
- wsprintf(ach, TEXT("Ref = %ld, Enumrn"), m_cRef+1);
- OutputDebugString(ach);
- #endif
- return ++m_cRef; // AddRef Application Object if enumerator will outlive application object
- }
- STDMETHODIMP_(ULONG)
- CEnumVariant::Release(void)
- {
- #ifdef _DEBUG
- TCHAR ach[50];
- wsprintf(ach, TEXT("Ref = %ld, Enumrn"), m_cRef-1);
- OutputDebugString(ach);
- #endif
- if(--m_cRef == 0)
- {
- delete this;
- return 0;
- }
- return m_cRef;
- }
- /*
- * CEnumVariant::Next
- *
- * Purpose:
- * Retrieves the next cElements elements. Implements IEnumVARIANT::Next.
- *
- */
- STDMETHODIMP
- CEnumVariant::Next(ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched)
- {
- HRESULT hr;
- ULONG l;
- long l1;
- ULONG l2;
- if (pcElementFetched != NULL)
- *pcElementFetched = 0;
- // Retrieve the next cElements elements.
- for (l1=m_lCurrent, l2=0; l1<(long)(m_lLBound+m_cElements) && l2<cElements; l1++, l2++)
- {
- hr = SafeArrayGetElement(m_psa, &l1, &pvar[l2]);
- if (FAILED(hr))
- goto error;
- }
- // Set count of elements retrieved
- if (pcElementFetched != NULL)
- *pcElementFetched = l2;
- m_lCurrent = l1;
- return (l2 < cElements) ? S_FALSE : NOERROR;
- error:
- for (l=0; l<cElements; l++)
- VariantClear(&pvar[l]);
- return hr;
- }
- /*
- * CEnumVariant::Skip
- *
- * Purpose:
- * Skips the next cElements elements. Implements IEnumVARIANT::Skip.
- *
- */
- STDMETHODIMP
- CEnumVariant::Skip(ULONG cElements)
- {
- m_lCurrent += cElements;
- if (m_lCurrent > (long)(m_lLBound+m_cElements))
- {
- m_lCurrent = m_lLBound+m_cElements;
- return S_FALSE;
- }
- else return NOERROR;
- }
- /*
- * CEnumVariant::Reset
- *
- * Purpose:
- * Resets the current element in the enumerator to the beginning. Implements IEnumVARIANT::Reset.
- *
- */
- STDMETHODIMP
- CEnumVariant::Reset()
- {
- m_lCurrent = m_lLBound;
- return NOERROR;
- }
- /*
- * CEnumVariant::Clone
- *
- * Purpose:
- * Creates a copy of the current enumeration state. Implements IEnumVARIANT::Clone.
- *
- */
- STDMETHODIMP
- CEnumVariant::Clone(IEnumVARIANT FAR* FAR* ppenum)
- {
- CEnumVariant FAR* penum = NULL;
- HRESULT hr;
- *ppenum = NULL;
- hr = CEnumVariant::Create(m_psa, m_cElements, &penum);
- if (FAILED(hr))
- goto error;
- penum->AddRef();
- penum->m_lCurrent = m_lCurrent;
- *ppenum = penum;
- return NOERROR;
- error:
- if (penum)
- penum->Release();
- return hr;
- }