|
|
1.1 ! root 1: /*** ! 2: *CPoly.cpp ! 3: * ! 4: * Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved. ! 5: * ! 6: *Purpose: ! 7: * This module implements the CPoly and CPolyCF 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: #include "cpoly.h" ! 21: #include "cenumpt.h" ! 22: ! 23: #ifndef _MAC ! 24: extern CStatBar FAR* g_psb; ! 25: #endif ! 26: ! 27: ! 28: // our global list of polygons. ! 29: // ! 30: POLYLINK FAR* g_ppolylink = (POLYLINK FAR*)NULL; ! 31: ! 32: // global count of polygons. ! 33: // ! 34: int g_cPoly = 0; ! 35: ! 36: ! 37: CPoly::CPoly() ! 38: { ! 39: m_refs = 0; ! 40: m_xorg = 0; ! 41: m_yorg = 0; ! 42: m_width = 0; ! 43: m_cPoints = 0; ! 44: ! 45: m_red = 0; ! 46: m_green = 0; ! 47: m_blue = 0; ! 48: ! 49: m_ppointlink = NULL; ! 50: m_ppointlinkLast = NULL; ! 51: } ! 52: ! 53: ! 54: /*** ! 55: *CPoly *CPoly::Create(void) ! 56: *Purpose: ! 57: * Create an instance of a CPoly object, and add it to the global ! 58: * list of polygons. ! 59: * ! 60: *Entry: ! 61: * None ! 62: * ! 63: *Exit: ! 64: * returns a polygon object, NULL the allocation failed. ! 65: * ! 66: ***********************************************************************/ ! 67: CPoly FAR* ! 68: CPoly::Create() ! 69: { ! 70: CPoly FAR* ppoly; ! 71: POLYLINK FAR* ppolylink; ! 72: ! 73: if((ppolylink = new FAR POLYLINK) == (POLYLINK FAR*)NULL) ! 74: return (CPoly FAR*)NULL; ! 75: ! 76: if((ppoly = new FAR CPoly()) == (CPoly FAR*)NULL) ! 77: return (CPoly FAR*)NULL; ! 78: ! 79: ppoly->AddRef(); ! 80: ! 81: // push the new polygon onto the front of the polygon list. ! 82: // ! 83: ++g_cPoly; ! 84: ! 85: ppolylink->ppoly = ppoly; ! 86: ! 87: ppolylink->next = g_ppolylink; ! 88: g_ppolylink = ppolylink; ! 89: ! 90: #ifndef _MAC ! 91: SBprintf(g_psb, "#poly = %d", g_cPoly); ! 92: #endif ! 93: ! 94: return ppoly; ! 95: } ! 96: ! 97: ! 98: //--------------------------------------------------------------------- ! 99: // IUnknown Methods ! 100: //--------------------------------------------------------------------- ! 101: ! 102: ! 103: STDMETHODIMP ! 104: CPoly::QueryInterface(REFIID riid, void FAR* FAR* ppv) ! 105: { ! 106: if(riid != IID_IUnknown){ ! 107: if(riid != IID_IDispatch){ ! 108: *ppv = NULL; ! 109: return ResultFromScode(E_NOINTERFACE); ! 110: } ! 111: } ! 112: ! 113: *ppv = this; ! 114: AddRef(); ! 115: return NOERROR; ! 116: } ! 117: ! 118: ! 119: STDMETHODIMP_(unsigned long) ! 120: CPoly::AddRef() ! 121: { ! 122: return ++m_refs; ! 123: } ! 124: ! 125: ! 126: STDMETHODIMP_(unsigned long) ! 127: CPoly::Release() ! 128: { ! 129: POLYLINK FAR* FAR* pppolylink, FAR* ppolylinkDead; ! 130: ! 131: if(--m_refs == 0){ ! 132: Reset(); // release all CPoints ! 133: ! 134: // remove ourselves from the global list of polygons ! 135: // ! 136: for( pppolylink = &g_ppolylink; ! 137: *pppolylink != NULL; ! 138: pppolylink = &(*pppolylink)->next) ! 139: { ! 140: if((*pppolylink)->ppoly == this){ ! 141: ppolylinkDead = *pppolylink; ! 142: *pppolylink = (*pppolylink)->next; ! 143: delete ppolylinkDead; ! 144: break; ! 145: } ! 146: } ! 147: ! 148: --g_cPoly; ! 149: ! 150: #ifndef _MAC ! 151: SBprintf(g_psb, "#poly = %d", g_cPoly); ! 152: #endif ! 153: ! 154: delete this; ! 155: return 0; ! 156: } ! 157: return m_refs; ! 158: } ! 159: ! 160: ! 161: //--------------------------------------------------------------------- ! 162: // IDispatch Methods ! 163: //--------------------------------------------------------------------- ! 164: ! 165: ! 166: /* ! 167: * NOTE: Support for the following two methods is not available ! 168: * in this version. ! 169: * ! 170: */ ! 171: ! 172: STDMETHODIMP ! 173: CPoly::GetTypeInfoCount(unsigned int FAR* pctinfo) ! 174: { ! 175: *pctinfo = 0; ! 176: return NOERROR; ! 177: } ! 178: ! 179: ! 180: STDMETHODIMP ! 181: CPoly::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo) ! 182: { ! 183: UNUSED(itinfo); ! 184: UNUSED(lcid); ! 185: UNUSED(pptinfo); ! 186: ! 187: return ResultFromScode(E_NOTIMPL); ! 188: } ! 189: ! 190: ! 191: /*** ! 192: *HRESULT CPoly::GetIDsOfNames(char**, unsigned int, LCID, long*) ! 193: *Purpose: ! 194: * This method translates the given array of names to a corresponding ! 195: * array of DISPIDs. ! 196: * ! 197: * This method deferrs to a common implementation shared by ! 198: * both the CPoly and CPoint objects. See the description of ! 199: * 'SPolyGetIDsOfNames()' in dispimpl.cpp for more information. ! 200: * ! 201: *Entry: ! 202: * rgszNames = pointer to an array of names ! 203: * cNames = the number of names in the rgszNames array ! 204: * lcid = the callers locale ID ! 205: * ! 206: *Exit: ! 207: * return value = HRESULT ! 208: * rgdispid = array of DISPIDs corresponding to the rgszNames array ! 209: * this array will contain -1 for each entry that is not known. ! 210: * ! 211: ***********************************************************************/ ! 212: STDMETHODIMP ! 213: CPoly::GetIDsOfNames( ! 214: REFIID riid, ! 215: char FAR* FAR* rgszNames, ! 216: unsigned int cNames, ! 217: LCID lcid, ! 218: DISPID FAR* rgdispid) ! 219: { ! 220: static PARAMDESC rgpdAddPoint[] = { ! 221: {"X"}, {"Y"} ! 222: }; ! 223: static MEMBERDESC rgmdCPoly[] = { ! 224: {"DRAW", IDMEMBER_CPOLY_DRAW, NULL, 0}, ! 225: {"RESET", IDMEMBER_CPOLY_RESET, NULL, 0}, ! 226: {"ADDPOINT", IDMEMBER_CPOLY_ADDPOINT, rgpdAddPoint, 2}, ! 227: {"ENUMPOINTS", IDMEMBER_CPOLY_ENUMPOINTS, NULL, 0}, ! 228: {"GETXORIGIN", IDMEMBER_CPOLY_GETXORIGIN, NULL, 0}, ! 229: {"SETXORIGIN", IDMEMBER_CPOLY_SETXORIGIN, NULL, 0}, ! 230: {"GETYORIGIN", IDMEMBER_CPOLY_GETYORIGIN, NULL, 0}, ! 231: {"SETYORIGIN", IDMEMBER_CPOLY_SETYORIGIN, NULL, 0}, ! 232: {"GETWIDTH", IDMEMBER_CPOLY_GETWIDTH, NULL, 0}, ! 233: {"SETWIDTH", IDMEMBER_CPOLY_SETWIDTH, NULL, 0}, ! 234: {"get_red", IDMEMBER_CPOLY_GETRED, NULL, 0}, ! 235: {"set_red", IDMEMBER_CPOLY_SETRED, NULL, 0}, ! 236: {"get_green", IDMEMBER_CPOLY_GETGREEN, NULL, 0}, ! 237: {"set_green", IDMEMBER_CPOLY_SETGREEN, NULL, 0}, ! 238: {"get_blue", IDMEMBER_CPOLY_GETBLUE, NULL, 0}, ! 239: {"set_blue", IDMEMBER_CPOLY_SETBLUE, NULL, 0}, ! 240: {"DUMP", IDMEMBER_CPOLY_DUMP, NULL, 0} ! 241: }; ! 242: ! 243: // this object only exposes a "default" interface. ! 244: // ! 245: if(riid != IID_NULL) ! 246: return ResultFromScode(DISP_E_UNKNOWNINTERFACE); ! 247: ! 248: return SPolyGetIDsOfNames( ! 249: rgmdCPoly, DIM(rgmdCPoly), rgszNames, cNames, lcid, rgdispid); ! 250: } ! 251: ! 252: ! 253: /*** ! 254: *HRESULT CPoly::Invoke(...) ! 255: *Purpose: ! 256: * Dispatch a method or property request for objects of type CPoly. ! 257: * ! 258: * see the IDispatch document for more information, and a general ! 259: * description of this method. ! 260: * ! 261: *Entry: ! 262: * dispidMember = the DISPID of the member being requested ! 263: * ! 264: * riid = reference to the interface ID of the interface on this object ! 265: * that the requested member belongs to. IID_NULL means to interpret ! 266: * the member as belonging to the implementation defined "default" ! 267: * or "primary" interface. ! 268: * ! 269: * lcid = the caller's locale ID ! 270: * ! 271: * wFlags = flags indicating the type of access being requested ! 272: * ! 273: * pdispparams = pointer to the DISPPARAMS struct containing the ! 274: * requested members arguments (if any) and its named parameter ! 275: * DISPIDs (if any). ! 276: * ! 277: *Exit: ! 278: * return value = HRESULT ! 279: * see the IDispatch spec for a description of possible success codes. ! 280: * ! 281: * pvarResult = pointer to a caller allocated VARIANT containing ! 282: * the members return value (if any). ! 283: * ! 284: * pexcepinfo = caller allocated exception info structure, this will ! 285: * be filled in only if an exception was raised that must be passed ! 286: * up through Invoke to an enclosing handler. ! 287: * ! 288: * puArgErr = pointer to a caller allocated UINT, that will contain the ! 289: * index of the offending argument if a DISP_E_TYPEMISMATCH error ! 290: * was returned indicating that one of the arguments was of an ! 291: * incorrect type and/or could not be reasonably coerced to a proper ! 292: * type. ! 293: * ! 294: ***********************************************************************/ ! 295: STDMETHODIMP ! 296: CPoly::Invoke( ! 297: DISPID dispidMember, ! 298: REFIID riid, ! 299: LCID lcid, ! 300: unsigned short wFlags, ! 301: DISPPARAMS FAR* pdispparams, ! 302: VARIANT FAR* pvarResult, ! 303: EXCEPINFO FAR* pexcepinfo, ! 304: unsigned int FAR* puArgErr) ! 305: { ! 306: HRESULT hresult; ! 307: VARIANTARG varg0, varg1; ! 308: VARIANT varResultDummy; ! 309: ! 310: UNUSED(lcid); ! 311: UNUSED(pexcepinfo); ! 312: ! 313: if(wFlags & ~(DISPATCH_METHOD | DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) ! 314: return ResultFromScode(E_INVALIDARG); ! 315: ! 316: // this object only exposes a "default" interface. ! 317: // ! 318: if(riid != IID_NULL) ! 319: return ResultFromScode(DISP_E_UNKNOWNINTERFACE); ! 320: ! 321: // This makes the following code a bit simpler if the caller ! 322: // happens to be ignoring the return value. Some implementations ! 323: // may choose to deal with this differently. ! 324: // ! 325: if(pvarResult == (VARIANT FAR*)NULL) ! 326: pvarResult = &varResultDummy; ! 327: ! 328: VariantInit(&varg0); ! 329: VariantInit(&varg1); ! 330: ! 331: // assume the return type is void, unless we find otherwise. ! 332: VariantInit(pvarResult); ! 333: ! 334: switch(dispidMember){ ! 335: case IDMEMBER_CPOLY_DRAW: ! 336: Draw(); ! 337: break; ! 338: ! 339: case IDMEMBER_CPOLY_RESET: ! 340: Reset(); ! 341: break; ! 342: ! 343: case IDMEMBER_CPOLY_DUMP: ! 344: Dump(); ! 345: break; ! 346: ! 347: case IDMEMBER_CPOLY_ADDPOINT: ! 348: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr); ! 349: if(hresult != NOERROR) ! 350: return hresult; ! 351: ! 352: hresult = DispGetParam(pdispparams, 1, VT_I2, &varg1, puArgErr); ! 353: if(hresult != NOERROR) ! 354: return hresult; ! 355: ! 356: hresult = AddPoint(V_I2(&varg1), V_I2(&varg0)); ! 357: if(hresult != NOERROR) ! 358: return hresult; ! 359: break; ! 360: ! 361: case IDMEMBER_CPOLY_ENUMPOINTS: ! 362: IEnumVARIANT FAR* penum; ! 363: ! 364: hresult = EnumPoints(&penum); ! 365: if(hresult != NOERROR) ! 366: return hresult; ! 367: ! 368: V_VT(pvarResult) = VT_UNKNOWN; ! 369: hresult = penum->QueryInterface( ! 370: IID_IUnknown, (void FAR* FAR*)&V_UNKNOWN(pvarResult)); ! 371: if(hresult != NOERROR) ! 372: return hresult; ! 373: penum->Release(); ! 374: break; ! 375: ! 376: case IDMEMBER_CPOLY_GETXORIGIN: ! 377: V_VT(pvarResult) = VT_I2; ! 378: V_I2(pvarResult) = m_xorg; ! 379: break; ! 380: ! 381: case IDMEMBER_CPOLY_SETXORIGIN: ! 382: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr); ! 383: if(hresult != NOERROR) ! 384: return hresult; ! 385: m_xorg = V_I2(&varg0); ! 386: break; ! 387: ! 388: case IDMEMBER_CPOLY_GETYORIGIN: ! 389: V_VT(pvarResult) = VT_I2; ! 390: V_I2(pvarResult) = m_yorg; ! 391: break; ! 392: ! 393: case IDMEMBER_CPOLY_SETYORIGIN: ! 394: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr); ! 395: if(hresult != NOERROR) ! 396: return hresult; ! 397: m_yorg = V_I2(&varg0); ! 398: break; ! 399: ! 400: case IDMEMBER_CPOLY_GETWIDTH: ! 401: V_VT(pvarResult) = VT_I2; ! 402: V_I2(pvarResult) = GetWidth(); ! 403: break; ! 404: ! 405: case IDMEMBER_CPOLY_SETWIDTH: ! 406: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr); ! 407: if(hresult != NOERROR) ! 408: return hresult; ! 409: SetWidth(V_I2(&varg0)); ! 410: break; ! 411: ! 412: case IDMEMBER_CPOLY_GETRED: ! 413: V_VT(pvarResult) = VT_I2; ! 414: V_I2(pvarResult) = get_red(); ! 415: break; ! 416: ! 417: case IDMEMBER_CPOLY_SETRED: ! 418: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr); ! 419: if(hresult != NOERROR) ! 420: return hresult; ! 421: set_red(V_I2(&varg0)); ! 422: break; ! 423: ! 424: case IDMEMBER_CPOLY_GETGREEN: ! 425: V_VT(pvarResult) = VT_I2; ! 426: V_I2(pvarResult) = get_green(); ! 427: break; ! 428: ! 429: case IDMEMBER_CPOLY_SETGREEN: ! 430: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr); ! 431: if(hresult != NOERROR) ! 432: return hresult; ! 433: set_green(V_I2(&varg0)); ! 434: break; ! 435: ! 436: case IDMEMBER_CPOLY_GETBLUE: ! 437: V_VT(pvarResult) = VT_I2; ! 438: V_I2(pvarResult) = get_blue(); ! 439: break; ! 440: ! 441: case IDMEMBER_CPOLY_SETBLUE: ! 442: hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr); ! 443: if(hresult != NOERROR) ! 444: return hresult; ! 445: set_blue(V_I2(&varg0)); ! 446: break; ! 447: ! 448: default: ! 449: return ResultFromScode(DISP_E_MEMBERNOTFOUND); ! 450: } ! 451: ! 452: return NOERROR; ! 453: } ! 454: ! 455: ! 456: //--------------------------------------------------------------------- ! 457: // Introduced Methods ! 458: //--------------------------------------------------------------------- ! 459: ! 460: ! 461: /*** ! 462: *void CPoly::Draw(void) ! 463: *Purpose: ! 464: * Draw the polygon, using the current x/y origin and line width ! 465: * properties. ! 466: * ! 467: *Entry: ! 468: * None ! 469: * ! 470: *Exit: ! 471: * None ! 472: * ! 473: ***********************************************************************/ ! 474: void PASCAL ! 475: CPoly::Draw() ! 476: { ! 477: short xorg, yorg; ! 478: POINTLINK FAR* ppointlinkFirst, FAR* ppointlink; ! 479: ! 480: if((ppointlinkFirst = m_ppointlink) == (POINTLINK FAR*)NULL) ! 481: return; ! 482: ! 483: #ifdef _MAC /* { */ ! 484: ! 485: short x, y; ! 486: RGBColor rgb; ! 487: WindowPtr pwndSaved; ! 488: extern WindowPtr g_pwndClient; ! 489: ! 490: GetPort(&pwndSaved); ! 491: SetPort(g_pwndClient); ! 492: ! 493: PenNormal(); ! 494: PenSize(m_width, m_width); ! 495: ! 496: rgb.red = m_red; ! 497: rgb.green = m_green; ! 498: rgb.blue = m_blue; ! 499: RGBForeColor(&rgb); ! 500: ! 501: xorg = m_xorg; ! 502: yorg = m_yorg; ! 503: ! 504: MoveTo( ! 505: xorg + ppointlinkFirst->ppoint->m_x, ! 506: yorg + ppointlinkFirst->ppoint->m_y); ! 507: ! 508: for(ppointlink = ppointlinkFirst->next; ! 509: ppointlink != (POINTLINK FAR*)NULL; ! 510: ppointlink = ppointlink->next) ! 511: { ! 512: x = xorg + ppointlink->ppoint->m_x; ! 513: y = yorg + ppointlink->ppoint->m_y; ! 514: LineTo(x, y); ! 515: } ! 516: ! 517: LineTo( ! 518: xorg + ppointlinkFirst->ppoint->m_x, ! 519: yorg + ppointlinkFirst->ppoint->m_y); ! 520: ! 521: SetPort(pwndSaved); ! 522: ! 523: #else /* }{ */ ! 524: ! 525: HDC hdc; ! 526: RECT rect; ! 527: HPEN hpen, hpenOld; ! 528: extern HWND g_hwndClient; ! 529: ! 530: GetClientRect(g_hwndClient, &rect); ! 531: xorg = m_xorg + (short) rect.left; ! 532: yorg = m_yorg + (short) rect.top; ! 533: ! 534: hdc = GetDC(g_hwndClient); ! 535: hpen = CreatePen(PS_SOLID, m_width, RGB(m_red, m_green, m_blue)); ! 536: hpenOld = SelectObject(hdc, hpen); ! 537: ! 538: #ifdef WIN32 ! 539: MoveToEx(hdc, ! 540: xorg + ppointlinkFirst->ppoint->m_x, ! 541: yorg + ppointlinkFirst->ppoint->m_y, NULL); ! 542: #else ! 543: MoveTo(hdc, ! 544: xorg + ppointlinkFirst->ppoint->m_x, ! 545: yorg + ppointlinkFirst->ppoint->m_y); ! 546: #endif ! 547: ! 548: for(ppointlink = ppointlinkFirst->next; ! 549: ppointlink != (POINTLINK FAR*)NULL; ! 550: ppointlink = ppointlink->next) ! 551: { ! 552: LineTo(hdc, ! 553: xorg + ppointlink->ppoint->m_x, ! 554: yorg + ppointlink->ppoint->m_y); ! 555: } ! 556: ! 557: LineTo(hdc, ! 558: xorg + ppointlinkFirst->ppoint->m_x, ! 559: yorg + ppointlinkFirst->ppoint->m_y); ! 560: ! 561: SelectObject(hdc, hpenOld); ! 562: DeleteObject(hpen); ! 563: ! 564: ReleaseDC(g_hwndClient, hdc); ! 565: ! 566: #endif /* } */ ! 567: } ! 568: ! 569: ! 570: /*** ! 571: *void CPoly::Reset(void) ! 572: *Purpose: ! 573: * Release all points referenced by this poly. ! 574: * ! 575: *Entry: ! 576: * None ! 577: * ! 578: *Exit: ! 579: * None ! 580: * ! 581: ***********************************************************************/ ! 582: void PASCAL ! 583: CPoly::Reset() ! 584: { ! 585: POINTLINK FAR* ppointlink, FAR* ppointlinkNext; ! 586: ! 587: for(ppointlink = m_ppointlink; ! 588: ppointlink != (POINTLINK FAR*)NULL; ! 589: ppointlink = ppointlinkNext) ! 590: { ! 591: ppointlinkNext = ppointlink->next; ! 592: ppointlink->ppoint->Release(); ! 593: delete ppointlink; ! 594: } ! 595: ! 596: m_cPoints = 0; ! 597: m_ppointlink = NULL; ! 598: m_ppointlinkLast = NULL; ! 599: } ! 600: ! 601: ! 602: /*** ! 603: *HRESULT CPoly::AddPoint(short, short) ! 604: *Purpose: ! 605: * Add a CPoint with the given coordinates to the end of our current ! 606: * list of points. ! 607: * ! 608: *Entry: ! 609: * x,y = the x and y coordinates of the new point. ! 610: * ! 611: *Exit: ! 612: * return value = HRESULT ! 613: * ! 614: ***********************************************************************/ ! 615: HRESULT PASCAL ! 616: CPoly::AddPoint(short x, short y) ! 617: { ! 618: CPoint FAR* ppoint; ! 619: POINTLINK FAR* ppointlink; ! 620: ! 621: ppoint = CPoint::Create(); ! 622: if(ppoint == (CPoint FAR*)NULL) ! 623: return ResultFromScode(E_OUTOFMEMORY); ! 624: ! 625: ppoint->SetX(x); ! 626: ppoint->SetY(y); ! 627: ! 628: ppointlink = new FAR POINTLINK; ! 629: if(ppointlink == (POINTLINK FAR*)NULL){ ! 630: delete ppoint; ! 631: return ResultFromScode(E_OUTOFMEMORY); ! 632: } ! 633: ! 634: ppointlink->ppoint = ppoint; ! 635: ppointlink->next = (POINTLINK FAR*)NULL; ! 636: ! 637: if(m_ppointlinkLast == (POINTLINK FAR*)NULL){ ! 638: m_ppointlink = m_ppointlinkLast = ppointlink; ! 639: }else{ ! 640: m_ppointlinkLast->next = ppointlink; ! 641: m_ppointlinkLast = ppointlink; ! 642: } ! 643: ! 644: ++m_cPoints; ! 645: ! 646: return NOERROR; ! 647: } ! 648: ! 649: ! 650: /*** ! 651: *HRESULT CPoly::EnumPoints(IEnumVARIANT**); ! 652: *Purpose: ! 653: * Return and enumerator for the points in this polygon. ! 654: * ! 655: *Entry: ! 656: * None ! 657: * ! 658: *Exit: ! 659: * return value = HRESULT ! 660: * ! 661: * *ppenum = pointer to an IEnumVARIANT for the points in this polygon ! 662: * ! 663: ***********************************************************************/ ! 664: HRESULT PASCAL ! 665: CPoly::EnumPoints(IEnumVARIANT FAR* FAR* ppenum) ! 666: { ! 667: unsigned int i; ! 668: VARIANT var; ! 669: HRESULT hresult; ! 670: SAFEARRAY FAR* psa; ! 671: CEnumPoint FAR* penum; ! 672: POINTLINK FAR* ppointlink; ! 673: SAFEARRAYBOUND rgsabound[1]; ! 674: ! 675: rgsabound[0].lLbound = 0; ! 676: rgsabound[0].cElements = m_cPoints; ! 677: ! 678: psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound); ! 679: if(psa == NULL){ ! 680: hresult = ResultFromScode(E_OUTOFMEMORY); ! 681: goto LError0; ! 682: } ! 683: ! 684: ppointlink = m_ppointlink; ! 685: for(i = 0; i < m_cPoints; ++i){ ! 686: long ix[1]; ! 687: ! 688: if(ppointlink == NULL){ ! 689: // this indicates an internal consistency error. ! 690: // (this test should probably be an assertion) ! 691: hresult = ResultFromScode(E_FAIL); ! 692: goto LError1; ! 693: } ! 694: ! 695: V_VT(&var) = VT_DISPATCH; ! 696: hresult = ppointlink->ppoint->QueryInterface( ! 697: IID_IDispatch, (void FAR* FAR*)&V_DISPATCH(&var)); ! 698: if(hresult != NOERROR) ! 699: goto LError1; ! 700: ! 701: ix[0] = i; ! 702: SafeArrayPutElement(psa, ix, &var); ! 703: ! 704: ppointlink = ppointlink->next; ! 705: } ! 706: ! 707: hresult = CEnumPoint::Create(psa, &penum); ! 708: if(hresult != NOERROR) ! 709: goto LError1; ! 710: ! 711: *ppenum = penum; ! 712: ! 713: return NOERROR; ! 714: ! 715: LError1:; ! 716: // destroy the array if we were not successful creating the enumerator. ! 717: SafeArrayDestroy(psa); ! 718: ! 719: LError0:; ! 720: return hresult; ! 721: } ! 722: ! 723: short PASCAL ! 724: CPoly::GetXOrigin() ! 725: { ! 726: return m_xorg; ! 727: } ! 728: ! 729: void PASCAL ! 730: CPoly::SetXOrigin(short x) ! 731: { ! 732: m_xorg = x; ! 733: } ! 734: ! 735: short PASCAL ! 736: CPoly::GetYOrigin() ! 737: { ! 738: return m_yorg; ! 739: } ! 740: ! 741: void PASCAL ! 742: CPoly::SetYOrigin(short y) ! 743: { ! 744: m_yorg = y; ! 745: } ! 746: ! 747: short PASCAL ! 748: CPoly::GetWidth() ! 749: { ! 750: return m_width; ! 751: } ! 752: ! 753: void PASCAL ! 754: CPoly::SetWidth(short width) ! 755: { ! 756: m_width = width; ! 757: } ! 758: ! 759: short PASCAL ! 760: CPoly::get_red() ! 761: { ! 762: return m_red; ! 763: } ! 764: ! 765: void PASCAL ! 766: CPoly::set_red(short red) ! 767: { ! 768: m_red = red; ! 769: } ! 770: ! 771: short PASCAL ! 772: CPoly::get_green() ! 773: { ! 774: return m_green; ! 775: } ! 776: ! 777: void PASCAL ! 778: CPoly::set_green(short green) ! 779: { ! 780: m_green = green; ! 781: } ! 782: ! 783: short PASCAL ! 784: CPoly::get_blue() ! 785: { ! 786: return m_blue; ! 787: } ! 788: ! 789: void PASCAL ! 790: CPoly::set_blue(short blue) ! 791: { ! 792: m_blue = blue; ! 793: } ! 794: ! 795: ! 796: /*** ! 797: *void CPoly::Dump(void) ! 798: *Purpose: ! 799: * Output a debug dump of this instance. ! 800: * ! 801: *Entry: ! 802: * None ! 803: * ! 804: *Exit: ! 805: * None ! 806: * ! 807: ***********************************************************************/ ! 808: void PASCAL ! 809: CPoly::Dump() ! 810: { ! 811: #ifdef _MAC ! 812: ! 813: // REVIEW: implement for the mac ! 814: ! 815: #else ! 816: ! 817: char buffer[80]; ! 818: POINTLINK FAR* ppointlink; ! 819: ! 820: wsprintf(buffer, "CPoly(0x%x) =\n", (int)this); ! 821: OutputDebugString(buffer); ! 822: ! 823: wsprintf(buffer, ! 824: " xorg = %d, yorg = %d, width = %d, rgb = {%d,%d,%d}\n points = ", ! 825: m_xorg, m_yorg, m_width, ! 826: get_red(), ! 827: get_green(), ! 828: get_blue()); ! 829: ! 830: OutputDebugString(buffer); ! 831: ! 832: for(ppointlink = m_ppointlink; ! 833: ppointlink != (POINTLINK FAR*)NULL; ! 834: ppointlink = ppointlink->next) ! 835: { ! 836: wsprintf(buffer, "{%d,%d}", ! 837: ppointlink->ppoint->GetX(), ! 838: ppointlink->ppoint->GetY()); ! 839: OutputDebugString(buffer); ! 840: ! 841: wsprintf(buffer, " "); ! 842: OutputDebugString(buffer); ! 843: } ! 844: wsprintf(buffer, "\n"); ! 845: OutputDebugString(buffer); ! 846: ! 847: #endif ! 848: } ! 849: ! 850: /*** ! 851: *void CPoly::PolyDraw(void) ! 852: *Purpose: ! 853: * Draw all polygons. ! 854: * ! 855: *Entry: ! 856: * None ! 857: * ! 858: *Exit: ! 859: * None ! 860: * ! 861: ***********************************************************************/ ! 862: void ! 863: CPoly::PolyDraw() ! 864: { ! 865: POLYLINK FAR* polylink; ! 866: ! 867: for(polylink = g_ppolylink; ! 868: polylink != (POLYLINK FAR*)NULL; ! 869: polylink = polylink->next) ! 870: { ! 871: polylink->ppoly->Draw(); ! 872: } ! 873: } ! 874: ! 875: ! 876: /*** ! 877: *void PolyTerm(void) ! 878: *Purpose: ! 879: * Release all polygons. ! 880: * ! 881: *Entry: ! 882: * None ! 883: * ! 884: *Exit: ! 885: * None ! 886: * ! 887: ***********************************************************************/ ! 888: void ! 889: CPoly::PolyTerm() ! 890: { ! 891: POLYLINK FAR* ppolylink; ! 892: POLYLINK FAR* ppolylinkNext; ! 893: ! 894: for(ppolylink = g_ppolylink; ! 895: ppolylink != (POLYLINK FAR*)NULL; ! 896: ppolylink = ppolylinkNext) ! 897: { ! 898: ppolylinkNext = ppolylink->next; ! 899: ppolylink->ppoly->Release(); ! 900: delete ppolylink; ! 901: } ! 902: } ! 903: ! 904: ! 905: /*** ! 906: *void PolyDump(void) ! 907: *Purpose: ! 908: * Invoke the debug Dump() method on all polygons were currently ! 909: * holding on to. ! 910: * ! 911: *Entry: ! 912: * None ! 913: * ! 914: *Exit: ! 915: * None ! 916: * ! 917: ***********************************************************************/ ! 918: void ! 919: CPoly::PolyDump() ! 920: { ! 921: POLYLINK FAR* ppolylink; ! 922: ! 923: if(g_ppolylink == (POLYLINK FAR*)NULL){ ! 924: #ifndef _MAC ! 925: OutputDebugString("\t(none)\n"); ! 926: #endif ! 927: return; ! 928: } ! 929: ! 930: for(ppolylink = g_ppolylink; ! 931: ppolylink != (POLYLINK FAR*)NULL; ! 932: ppolylink = ppolylink->next) ! 933: { ! 934: ppolylink->ppoly->Dump(); ! 935: } ! 936: } ! 937: ! 938: ! 939: //--------------------------------------------------------------------- ! 940: // Implementation of the CPoly Class Factory ! 941: //--------------------------------------------------------------------- ! 942: ! 943: ! 944: CPolyCF::CPolyCF() ! 945: { ! 946: m_refs = 0; ! 947: } ! 948: ! 949: IClassFactory FAR* ! 950: CPolyCF::Create() ! 951: { ! 952: CPolyCF FAR* pCF; ! 953: ! 954: if((pCF = new FAR CPolyCF()) == NULL) ! 955: return NULL; ! 956: pCF->AddRef(); ! 957: return pCF; ! 958: } ! 959: ! 960: STDMETHODIMP ! 961: CPolyCF::QueryInterface(REFIID riid, void FAR* FAR* ppv) ! 962: { ! 963: if(riid != IID_IUnknown){ ! 964: if(riid != IID_IClassFactory){ ! 965: *ppv = NULL; ! 966: return ResultFromScode(E_NOINTERFACE); ! 967: } ! 968: } ! 969: ! 970: *ppv = this; ! 971: ++m_refs; ! 972: return NOERROR; ! 973: } ! 974: ! 975: STDMETHODIMP_(unsigned long) ! 976: CPolyCF::AddRef(void) ! 977: { ! 978: return ++m_refs; ! 979: } ! 980: ! 981: STDMETHODIMP_(unsigned long) ! 982: CPolyCF::Release(void) ! 983: { ! 984: if(--m_refs == 0){ ! 985: delete this; ! 986: return 0; ! 987: } ! 988: return m_refs; ! 989: } ! 990: ! 991: STDMETHODIMP ! 992: CPolyCF::CreateInstance( ! 993: IUnknown FAR* punkOuter, ! 994: REFIID iid, ! 995: void FAR* FAR* ppv) ! 996: { ! 997: HRESULT hresult; ! 998: CPoly FAR *ppoly; ! 999: ! 1000: UNUSED(punkOuter); ! 1001: ! 1002: #ifdef _MAC ! 1003: if(GetZone() != ApplicZone()){ ! 1004: DebugStr("\pZones do not match"); ! 1005: } ! 1006: ! 1007: #endif ! 1008: ! 1009: if((ppoly = CPoly::Create()) == NULL){ ! 1010: *ppv = NULL; ! 1011: return ResultFromScode(E_OUTOFMEMORY); ! 1012: } ! 1013: hresult = ppoly->QueryInterface(iid, ppv); ! 1014: ppoly->Release(); ! 1015: return hresult; ! 1016: } ! 1017: ! 1018: STDMETHODIMP ! 1019: #ifdef _MAC ! 1020: CPolyCF::LockServer(unsigned long fLock) ! 1021: #else ! 1022: CPolyCF::LockServer(BOOL fLock) ! 1023: #endif ! 1024: { ! 1025: UNUSED(fLock); ! 1026: ! 1027: return NOERROR; ! 1028: } ! 1029:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.