home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / spoly2 / cpoly.cpp < prev    next >
C/C++ Source or Header  |  1997-08-01  |  20KB  |  934 lines

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