|
|
1.1 root 1: /***
2: *cenumpt.cpp
3: *
4: * Copyright (C) 1992, Microsoft Corporation. All Rights Reserved.
5: * Information Contained Herein Is Proprietary and Confidential.
6: *
7: *Purpose:
8: * This module implements the CEnumPoint class.
9: *
10: *
11: *Implementation Notes:
12: *
13: *****************************************************************************/
14:
15: #include <windows.h>
16: #include <ole2.h>
17: #include <dispatch.h>
18:
19: #include "cenumpt.h"
20:
21:
22: CEnumPoint::CEnumPoint()
23: {
24: m_refs = 0;
25:
26: m_psa = NULL;
27: m_celts = 0;
28: m_iCurrent = 0;
29: }
30:
31:
32: /***
33: *HRESULT CEnumPoint::Create(SAFEARRAY*, CEnumPoint**)
34: *Purpose:
35: * This routine creates a CPoint enumerator from the given
36: * (1 X N) SafeArray of CPoint IDispatch pointers.
37: *
38: *Entry:
39: * psa = pointer to a SafeArray of VARIANTs
40: *
41: *Exit:
42: * return value = HRESULT
43: *
44: * *ppenum = pointer to a CPoint enumerator
45: *
46: ***********************************************************************/
47: HRESULT
48: CEnumPoint::Create(SAFEARRAY FAR* psa, CEnumPoint FAR* FAR* ppenum)
49: {
50: LONG lBound;
51: HRESULT hresult;
52: CEnumPoint FAR* penum;
53:
54:
55: // Verify that the SafeArray is the proper shape.
56: //
57: if(SafeArrayGetDim(psa) != 1)
58: return ResultFromScode(E_INVALIDARG);
59:
60: hresult = SafeArrayGetLBound(psa, 1, &lBound);
61: if(FAILED(hresult))
62: return hresult;
63:
64: if(lBound != 0)
65: return ResultFromScode(E_INVALIDARG);
66:
67: penum = new FAR CEnumPoint();
68: if(penum == NULL)
69: return ResultFromScode(E_OUTOFMEMORY);
70: penum->AddRef();
71:
72: hresult = SafeArrayGetUBound(psa, 1, &lBound);
73: if(FAILED(hresult))
74: goto LError0;
75:
76: penum->m_psa = psa;
77: penum->m_celts = lBound + 1;
78:
79: *ppenum = penum;
80:
81: return NOERROR;
82:
83: LError0:;
84: penum->Release();
85:
86: return hresult;
87: }
88:
89:
90: //---------------------------------------------------------------------
91: // IUnknown methods
92: //---------------------------------------------------------------------
93:
94:
95: STDMETHODIMP
96: CEnumPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
97: {
98: if(riid == IID_IEnumVARIANT || riid == IID_IUnknown){
99: *ppv = this;
100: AddRef();
101: return NOERROR;
102: }
103: return ResultFromScode(E_NOINTERFACE);
104: }
105:
106:
107: STDMETHODIMP_(ULONG)
108: CEnumPoint::AddRef()
109: {
110: return ++m_refs;
111: }
112:
113:
114: STDMETHODIMP_(ULONG)
115: CEnumPoint::Release()
116: {
117: if(--m_refs == 0){
118: if(m_psa != NULL)
119: SafeArrayDestroy(m_psa);
120: delete this;
121: return 0;
122: }
123: return m_refs;
124: }
125:
126:
127: //---------------------------------------------------------------------
128: // IEnumVARIANT methods
129: //---------------------------------------------------------------------
130:
131:
132: /***
133: *HRESULT CEnumPoint::Next(ULONG, VARIANT*, ULONG*)
134: *Purpose:
135: * Attempt to get the next 'celt' items in the enumeration sequence.
136: *
137: *Entry:
138: * celt = the number of elements to get
139: *
140: *Exit:
141: * return value = HRESULT
142: * S_OK
143: * S_FALSE - the end of the sequence was reached
144: *
145: * rgvar = array of the next 'celt' items
146: * *pceltFetched = count of the elements actually fetched.
147: *
148: ***********************************************************************/
149: STDMETHODIMP
150: CEnumPoint::Next(
151: ULONG celt,
152: VARIANT FAR* rgvar,
153: ULONG FAR* pceltFetched)
154: {
155: UINT i;
156: LONG ix;
157: HRESULT hresult;
158:
159:
160: for(i = 0; i < celt; ++i)
161: VariantInit(&rgvar[i]);
162:
163: for(i = 0; i < celt; ++i){
164: if(m_iCurrent == m_celts){
165: hresult = ResultFromScode(S_FALSE);
166: goto LDone;
167: }
168:
169: ix = m_iCurrent++;
170: hresult = SafeArrayGetElement(m_psa, &ix, &rgvar[i]);
171: if(FAILED(hresult))
172: goto LError0;
173: }
174:
175: hresult = NOERROR;
176:
177: LDone:;
178: *pceltFetched = i;
179:
180: return hresult;
181:
182: LError0:;
183:
184: for(i = 0; i < celt; ++i)
185: VariantClear(&rgvar[i]);
186:
187: return hresult;
188: }
189:
190:
191: /***
192: *HRESULT CEnumPoint::Skip(ULONG)
193: *Purpose:
194: * Attempt to skip over the next 'celt' elements in the enumeration
195: * sequence.
196: *
197: *Entry:
198: * celt = the count of elements to skip
199: *
200: *Exit:
201: * return value = HRESULT
202: * S_OK
203: * S_FALSE - the end of the sequence was reached
204: *
205: ***********************************************************************/
206: STDMETHODIMP
207: CEnumPoint::Skip(ULONG celt)
208: {
209: m_iCurrent += celt;
210:
211: if(m_iCurrent > m_celts)
212: m_iCurrent = m_celts;
213:
214: return (m_iCurrent == m_celts)
215: ? ResultFromScode(S_FALSE) : NOERROR;
216: }
217:
218:
219: /***
220: *HRESULT CEnumPoint::Reset(void)
221: *Purpose:
222: * Reset the enumeration sequence back to the beginning.
223: *
224: *Entry:
225: * None
226: *
227: *Exit:
228: * return value = SHRESULT CODE
229: * S_OK
230: *
231: ***********************************************************************/
232: STDMETHODIMP
233: CEnumPoint::Reset()
234: {
235: m_iCurrent = 0;
236:
237: return NOERROR;
238: }
239:
240:
241: /***
242: *HRESULT CEnumPoint::Clone(IEnumVARIANT**)
243: *Purpose:
244: * Retrun a CPoint enumerator with exactly the same state as the
245: * current one.
246: *
247: *Entry:
248: * None
249: *
250: *Exit:
251: * return value = HRESULT
252: * S_OK
253: * E_OUTOFMEMORY
254: *
255: ***********************************************************************/
256: STDMETHODIMP
257: CEnumPoint::Clone(IEnumVARIANT FAR* FAR* ppenum)
258: {
259: HRESULT hresult;
260: SAFEARRAY FAR* psa;
261: CEnumPoint FAR* penum;
262:
263: hresult = SafeArrayCopy(m_psa, &psa);
264: if(FAILED(hresult))
265: return hresult;
266:
267: hresult = CEnumPoint::Create(psa, &penum);
268: if(FAILED(hresult))
269: goto LError0;
270:
271: // Assert(penum->m_celts == m_celts);
272:
273: penum->m_iCurrent = m_iCurrent;
274:
275: *ppenum = penum;
276:
277: return NOERROR;
278:
279: LError0:
280: SafeArrayDestroy(psa);
281:
282: return hresult;
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.