|
|
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.