|
|
1.1 root 1: /***
2: *cpoint.cpp
3: *
4: * Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved.
5: *
6: *Purpose:
7: * This module implements the CPoint and CPointCF classes.
8: *
9: * This module is intended as a sample implementation of the IDispatch
10: * interface, and its purpose is to demonstrate how an object can
11: * expose methods and properties for programatic and cross-process
12: * access via the IDispatch interface.
13: *
14: *Implementation Notes:
15: *
16: *****************************************************************************/
17:
18: #include "spoly.h"
19: #include "cpoint.h"
20:
21:
22: CPoint::CPoint()
23: {
24: m_x = 0;
25: m_y = 0;
26: m_refs = 0;
27: }
28:
29: /***
30: *CPoint::Create(void)
31: *Purpose:
32: * Create an instance of a CPoint object.
33: *
34: *Entry:
35: * None
36: *
37: *Exit:
38: * returns a CPoint*, NULL if creation failed.
39: *
40: ***********************************************************************/
41: CPoint FAR*
42: CPoint::Create()
43: {
44: CPoint FAR* ppoint;
45:
46: if((ppoint = new FAR CPoint()) == NULL)
47: return NULL;
48: ppoint->AddRef();
49: return ppoint;
50: }
51:
52:
53: //---------------------------------------------------------------------
54: // IUnknown Methods
55: //---------------------------------------------------------------------
56:
57:
58: STDMETHODIMP
59: CPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
60: {
61: if(riid != IID_IUnknown)
62: if(riid != IID_IDispatch)
63: return ResultFromScode(E_NOINTERFACE);
64:
65: *ppv = this;
66: AddRef();
67: return NOERROR;
68: }
69:
70:
71: STDMETHODIMP_(unsigned long)
72: CPoint::AddRef(void)
73: {
74: return ++m_refs;
75: }
76:
77:
78: STDMETHODIMP_(unsigned long)
79: CPoint::Release(void)
80: {
81: if(--m_refs == 0){
82: delete this;
83: return 0;
84: }
85: return m_refs;
86: }
87:
88:
89: //---------------------------------------------------------------------
90: // IDispatch methods
91: //---------------------------------------------------------------------
92:
93: /*
94: * NOTE: Support for the following two methods is not available
95: * in this version.
96: *
97: */
98:
99: STDMETHODIMP
100: CPoint::GetTypeInfoCount(unsigned int FAR* pctinfo)
101: {
102: *pctinfo = 0;
103: return NOERROR;
104: }
105:
106:
107: STDMETHODIMP
108: CPoint::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
109: {
110: UNUSED(itinfo);
111: UNUSED(lcid);
112: UNUSED(pptinfo);
113:
114: return ResultFromScode(E_NOTIMPL);
115: }
116:
117:
118: /***
119: *HRESULT CPoint::GetIDsOfNames(REFIID, char**, unsigned int, LCID, long*)
120: *Purpose:
121: * This method translates the given array of names to a corresponding
122: * array of DISPIDs.
123: *
124: * Index 0 of the name array is the member name, and indices 1-N if
125: * present represent named parameters on that member.
126: *
127: * The local ID ('lcid') is unused by this naive implementation. A more
128: * sophisticated implementation, sensitive to localization and natural
129: * language support would use the locale ID to interpret the given names
130: * in a correct locale specific context.
131: *
132: *Entry:
133: * rgszNames = pointer to an array of names
134: * cNames = the number of names in the rgszNames array
135: * lcid = the callers locale ID
136: *
137: *Exit:
138: * return value = HRESULT
139: * rgid = array of name IDs corresponding to the rgszNames array
140: * this array will contain -1 for each entry that is not known.
141: *
142: ***********************************************************************/
143: STDMETHODIMP
144: CPoint::GetIDsOfNames(
145: REFIID riid,
146: char FAR* FAR* rgszNames,
147: unsigned int cNames,
148: LCID lcid,
149: DISPID FAR* rgdispid)
150: {
151: static MEMBERDESC rgmdCPoint[] = {
152: {"GETX", IDMEMBER_CPOINT_GETX, NULL, 0},
153: {"SETX", IDMEMBER_CPOINT_SETX, NULL, 0},
154: {"GETY", IDMEMBER_CPOINT_GETY, NULL, 0},
155: {"SETY", IDMEMBER_CPOINT_SETY, NULL, 0}
156: };
157:
158: // this object only exposed the "default" interface.
159: //
160: if(riid != IID_NULL)
161: return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
162:
163: return SPolyGetIDsOfNames(
164: rgmdCPoint, DIM(rgmdCPoint), rgszNames, cNames, lcid, rgdispid);
165: }
166:
167:
168: /***
169: *HRESULT CPoint::Invoke(...)
170: *Purpose:
171: * Dispatch a method or property request for objects of type CPoint.
172: *
173: * see the IDispatch document for more information, and a general
174: * description of this method.
175: *
176: *Entry:
177: * dispidMember = the DISPID of the member being requested
178: *
179: * riid = reference to the interface ID of the interface on this object
180: * that the requested member belongs to. IID_NULL means to interpret
181: * the member as belonging to the implementation defined "default"
182: * or "primary" interface.
183: *
184: * lcid = the caller's locale ID
185: *
186: * wFlags = flags indicating the type of access being requested
187: *
188: * pdispparams = pointer to the DISPPARAMS struct containing the
189: * requested members arguments (if any) and its named parameter
190: * DISPIDs (if any).
191: *
192: *Exit:
193: * return value = HRESULT
194: * see the IDispatch spec for a description of possible success codes.
195: *
196: * pvarResult = pointer to a caller allocated VARIANT containing
197: * the members return value (if any).
198: *
199: * pexcepinfo = caller allocated exception info structure, this will
200: * be filled in only if an exception was raised that must be passed
201: * up through Invoke to an enclosing handler.
202: *
203: * puArgErr = pointer to a caller allocated UINT, that will contain the
204: * index of the offending argument if a DISP_E_TYPEMISMATCH error
205: * was returned indicating that one of the arguments was of an
206: * incorrect type and/or could not be reasonably coerced to a proper
207: * type.
208: *
209: ***********************************************************************/
210: STDMETHODIMP
211: CPoint::Invoke(
212: DISPID dispidMember,
213: REFIID riid,
214: LCID lcid,
215: unsigned short wFlags,
216: DISPPARAMS FAR* pdispparams,
217: VARIANT FAR* pvarResult,
218: EXCEPINFO FAR* pexcepinfo,
219: unsigned int FAR* puArgErr)
220: {
221: unsigned int uArgErr;
222: HRESULT hresult;
223: VARIANTARG varg0;
224: VARIANT varResultDummy;
225:
226: UNUSED(lcid);
227: UNUSED(pexcepinfo);
228:
229: // make sure the wFlags are legal
230: if(wFlags & ~(DISPATCH_METHOD | DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
231: return ResultFromScode(E_INVALIDARG);
232:
233: // this object only exposes a "default" interface.
234: //
235: if(riid != IID_NULL)
236: return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
237:
238: // this makes the following code a bit simpler
239: if(puArgErr == NULL)
240: puArgErr = &uArgErr;
241: if(pvarResult == NULL)
242: pvarResult = &varResultDummy;
243:
244: VariantInit(&varg0);
245:
246: // assume the return type is void, unless we find otherwise.
247: VariantInit(pvarResult);
248:
249: switch(dispidMember){
250: case IDMEMBER_CPOINT_GETX:
251: V_VT(pvarResult) = VT_I2;
252: V_I2(pvarResult) = GetX();
253: break;
254:
255: case IDMEMBER_CPOINT_SETX:
256: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);
257: if(hresult != NOERROR)
258: return hresult;
259: SetX(V_I2(&varg0));
260: break;
261:
262: case IDMEMBER_CPOINT_GETY:
263: V_VT(pvarResult) = VT_I2;
264: V_I2(pvarResult) = GetY();
265: break;
266:
267: case IDMEMBER_CPOINT_SETY:
268: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);
269: if(hresult != NOERROR)
270: return hresult;
271: SetY(V_I2(&varg0));
272: break;
273:
274: default:
275: return ResultFromScode(DISP_E_MEMBERNOTFOUND);
276: }
277: return NOERROR;
278: }
279:
280: short PASCAL
281: CPoint::GetX()
282: {
283: return m_x;
284: }
285:
286: void PASCAL
287: CPoint::SetX(short x)
288: {
289: m_x = x;
290: }
291:
292: short PASCAL
293: CPoint::GetY()
294: {
295: return m_y;
296: }
297:
298: void PASCAL
299: CPoint::SetY(short y)
300: {
301: m_y = y;
302: }
303:
304:
305: //---------------------------------------------------------------------
306: // Implementation of the CPoint Class Factory
307: //---------------------------------------------------------------------
308:
309: CPointCF::CPointCF()
310: {
311: m_refs = 0;
312: }
313:
314: IClassFactory FAR*
315: CPointCF::Create()
316: {
317: CPointCF FAR* pCF;
318:
319: if((pCF = new FAR CPointCF()) == NULL)
320: return NULL;
321: pCF->AddRef();
322: return pCF;
323: }
324:
325: STDMETHODIMP
326: CPointCF::QueryInterface(REFIID riid, void FAR* FAR* ppv)
327: {
328: if(riid != IID_IUnknown)
329: if(riid != IID_IClassFactory)
330: return ResultFromScode(E_NOINTERFACE);
331:
332: *ppv = this;
333: ++m_refs;
334: return NOERROR;
335: }
336:
337: STDMETHODIMP_(unsigned long)
338: CPointCF::AddRef(void)
339: {
340: return ++m_refs;
341: }
342:
343: STDMETHODIMP_(unsigned long)
344: CPointCF::Release(void)
345: {
346: if(--m_refs == 0){
347: delete this;
348: return 0;
349: }
350: return m_refs;
351: }
352:
353: STDMETHODIMP
354: CPointCF::CreateInstance(
355: IUnknown FAR* punkOuter,
356: REFIID riid,
357: void FAR* FAR* ppv)
358: {
359: HRESULT hresult;
360: CPoint FAR *ppoint;
361:
362: UNUSED(punkOuter);
363:
364: if((ppoint = CPoint::Create()) == NULL){
365: *ppv = NULL;
366: return ResultFromScode(E_OUTOFMEMORY);
367: }
368: hresult = ppoint->QueryInterface(riid, ppv);
369: ppoint->Release();
370: return hresult;
371: }
372:
373: STDMETHODIMP
374: #ifdef _MAC
375: CPointCF::LockServer(unsigned long fLock)
376: #else
377: CPointCF::LockServer(BOOL fLock)
378: #endif
379: {
380: UNUSED(fLock);
381:
382: return NOERROR;
383: }
384:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.