CPOLY.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:19k
源码类别:

Windows编程

开发平台:

Visual C++

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