home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-01-02 | 5.0 KB | 238 lines | [TEXT/????] |
- //
- // CXEnumGeneric.cpp
- //
- // Copyright (C) Microsoft Corporation, 1996
- //
- // Standard implementation of an enumerator interface.
-
- #define FAR
- #include "config.h"
-
- #include <ole2.h>
- #include <dispatch.h>
- #include <wintypes.h>
- #include "CXEnumGeneric.h"
- #include "debug.h"
-
- void ReleaseInterfacePtrs(LPUNKNOWN *punkArray, ULONG cElements);
- void CopyInterfacePtr(LPUNKNOWN *pTo, LPUNKNOWN *pFrom);
- void CopyFORMATETC(LPFORMATETC pTo, LPFORMATETC pFrom);
-
-
- CXEnumGeneric::CXEnumGeneric(LPVOID pvArray, ULONG cElements, LPENUMTYPE
- penumtype)
- {
- // Our implementation of the "new" operator will zero the structure so we
- // don't have to explicitly zero/null anything.
- m_cRef = 1;
- m_pvArray = pvArray;
- m_cElements = cElements;
- m_CurrentElement = 0;
- m_penumtype = penumtype;
- m_pClonedFrom = NULL;
- }
-
- CXEnumGeneric::~CXEnumGeneric()
- {
- if (m_pClonedFrom != NULL) {
- m_pClonedFrom->Release();
- } else {
- if (m_pvArray != NULL) {
- if (m_penumtype->pfnReleaseArray != NULL)
- m_penumtype->pfnReleaseArray(m_pvArray, m_cElements);
- CoTaskMemFree(m_pvArray);
- }
- }
- }
-
- //
- // CXEnumGeneric::IUnknown::QueryInterface
- //
- // Returns a pointer to the specified interface on a component to which a
- // client currently holds an interface pointer.
- //
-
- STDMETHODIMP
- CXEnumGeneric::QueryInterface(REFIID riid, LPVOID *ppvObj)
- {
- HRESULT hr;
- LPVOID pv;
-
- if (riid == IID_IUnknown || riid == *m_penumtype->piid) {
- pv = (LPVOID)(LPENUMGENERIC) this;
- ++m_cRef;
- hr = ResultFromScode(S_OK);
- } else {
- pv = NULL;
- hr = ResultFromScode(E_NOINTERFACE);
- }
-
- *ppvObj = pv;
- return hr;
- }
-
- //
- // CXEnumGeneric::IUnknown::AddRef
- //
- // Increments the reference count for the calling interface.
- //
-
- STDMETHODIMP_(ULONG)
- CXEnumGeneric::AddRef(void)
- {
- return ++m_cRef;
- }
-
- //
- // CXEnumGeneric::IUnknown::Release
- //
- // Decrements the reference count for the calling interface on a object. If
- // the reference count on the object falls to zero, the object is freed.
- //
-
- STDMETHODIMP_(ULONG)
- CXEnumGeneric::Release(void)
- {
- if (--m_cRef != 0)
- return m_cRef;
-
- delete this;
- return 0;
- }
-
- //
- // CXEnumGeneric::IEnumGeneric::Next
- //
-
- STDMETHODIMP
- CXEnumGeneric::Next(ULONG celt, LPVOID rgelt, ULONG *pceltFetched)
- {
- HRESULT hr;
- ULONG celtFetched;
- ULONG current;
- LPBYTE pFrom;
- LPBYTE pTo;
-
- if (m_CurrentElement + celt <= m_cElements) {
- hr = ResultFromScode(S_OK);
- celtFetched = celt;
- } else {
- hr = ResultFromScode(S_FALSE);
- celtFetched = m_cElements - m_CurrentElement;
- }
-
- if (pceltFetched != NULL)
- *pceltFetched = celtFetched;
-
- pTo = (LPBYTE) rgelt;
- pFrom = ((LPBYTE) m_pvArray) + (m_CurrentElement * m_penumtype->cbElement);
-
- for (current = 0; current < celtFetched; current++) {
- m_penumtype->pfnCopyElement((LPVOID) pTo, (LPVOID) pFrom);
- pTo += m_penumtype->cbElement;
- pFrom += m_penumtype->cbElement;
- m_CurrentElement++;
- }
-
- return hr;
- }
-
- //
- // CXEnumGeneric::IEnumGeneric::Skip
- //
-
- STDMETHODIMP
- CXEnumGeneric::Skip(ULONG celt)
- {
- HRESULT hr;
-
- if (m_CurrentElement + celt <= m_cElements) {
- m_CurrentElement += celt;
- hr = ResultFromScode(S_OK);
- } else {
- m_CurrentElement = m_cElements;
- hr = ResultFromScode(S_FALSE);
- }
-
- return hr;
- }
-
- //
- // CXEnumGeneric::IEnumGeneric::Reset
- //
-
- STDMETHODIMP
- CXEnumGeneric::Reset(void)
- {
- m_CurrentElement = 0;
- return ResultFromScode(S_OK);
- }
-
- //
- // CXEnumGeneric::IEnumGeneric::Clone
- //
-
- STDMETHODIMP
- CXEnumGeneric::Clone(LPENUMGENERIC *ppenum)
- {
- HRESULT hr;
- CXEnumGeneric *penumClone;
-
- // The clone will hold a reference to our object; m_pvArray will go away
- // when all clones and the original object have a total reference count of
- // zero.
- if ((penumClone = new CXEnumGeneric(m_pvArray, m_cElements, m_penumtype)) !=
- NULL) {
- penumClone->m_pClonedFrom = this;
- ++m_cRef;
- *ppenum = (LPENUMGENERIC) penumClone;
- hr = ResultFromScode(S_OK);
- } else {
- hr = ResultFromScode(E_OUTOFMEMORY);
- }
-
- return hr;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // IEnumUnknown support
-
- void
- CopyInterfacePtr(LPUNKNOWN *pTo, LPUNKNOWN *pFrom)
- {
- *pTo = *pFrom;
- (*pTo)->AddRef();
- }
-
- void
- ReleaseInterfacePtrs(LPUNKNOWN *punkArray, ULONG cElements)
- {
- for (ULONG current = 0; current < cElements; current++)
- punkArray[current]->Release();
- }
-
- ENUMTYPE g_EnumUnknown =
- {
- &IID_IEnumUnknown,
- sizeof(LPUNKNOWN),
- (LPFNENUMCOPYELEMENT) CopyInterfacePtr,
- (LPFNENUMRELEASEARRAY) ReleaseInterfacePtrs
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // IEnumWINFORMATETC support
-
- void
- CopyFORMATETC(LPFORMATETC pTo, LPFORMATETC pFrom)
- {
- *pTo = *pFrom;
- }
-
- ENUMTYPE g_EnumFORMATETC =
- {
- &IID_IEnumFORMATETC,
- sizeof(FORMATETC),
- (LPFNENUMCOPYELEMENT) CopyFORMATETC,
- (LPFNENUMRELEASEARRAY) NULL
- };
-