home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap19 / hcosmo / figure.cpp next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  10.2 KB  |  422 lines

  1. /*
  2.  * FIGURE.CPP
  3.  * Cosmo Handler Chapter 19
  4.  *
  5.  * Implementation of the CFigure class that we expose as a
  6.  * CosmoFigure Object in this handler.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "hcosmo.h"
  17.  
  18.  
  19. /*
  20.  * CFigure:CFigure
  21.  * CFigure::~CFigure
  22.  *
  23.  * Constructor Parameters:
  24.  *  pUnkOuter       LPUNKNOWN of the controlling unknown.
  25.  *  pfnDestroy      PFNDESTROYED to call when object is destroyed.
  26.  *  hInst           HINSTANCE of the application we're in.
  27.  */
  28.  
  29. CFigure::CFigure(LPUNKNOWN pUnkOuter, PFNDESTROYED pfnDestroy
  30.     , HINSTANCE hInst)
  31.     {
  32.     m_cRef=0;
  33.     m_pUnkOuter=pUnkOuter;
  34.     m_pfnDestroy=pfnDestroy;
  35.     m_clsID=CLSID_CosmoFigure;
  36.  
  37.     m_cf=RegisterClipboardFormat(SZPOLYLINECLIPFORMAT);
  38.  
  39.     //NULL any contained interfaces initially.
  40.     m_pImpIOleObject     =NULL;
  41.     m_pImpIViewObject2   =NULL;
  42.     m_pImpIPersistStorage=NULL;
  43.     m_pImpIAdviseSink    =NULL;
  44.  
  45.     m_pDefIUnknown       =NULL;
  46.     m_pDefIOleObject     =NULL;
  47.     m_pDefIViewObject2   =NULL;
  48.     m_pDefIPersistStorage=NULL;
  49.     m_pDefIDataObject    =NULL;
  50.  
  51.     m_pIAdvSinkView      =NULL;
  52.     m_dwAdviseFlags      =0;
  53.     m_dwAdviseAspects    =0;
  54.     m_dwFrozenAspects    =0;
  55.  
  56.     return;
  57.     }
  58.  
  59.  
  60. CFigure::~CFigure(void)
  61.     {
  62.     LPUNKNOWN       pIUnknown=this;
  63.  
  64.     if (NULL!=m_pUnkOuter)
  65.         pIUnknown=m_pUnkOuter;
  66.  
  67.     /*
  68.      * In aggregation, release cached pointers but
  69.      * AddRef the controlling unknown first.
  70.      */
  71.     if (NULL!=m_pDefIOleObject)
  72.         {
  73.         pIUnknown->AddRef();
  74.         m_pDefIOleObject->Release();
  75.         }
  76.  
  77.     if (NULL!=m_pDefIViewObject2)
  78.         {
  79.         pIUnknown->AddRef();
  80.         m_pDefIViewObject2->Release();
  81.         }
  82.  
  83.     if (NULL!=m_pDefIDataObject)
  84.         {
  85.         pIUnknown->AddRef();
  86.         m_pDefIDataObject->Release();
  87.         }
  88.  
  89.     if (NULL!=m_pDefIPersistStorage)
  90.         {
  91.         pIUnknown->AddRef();
  92.         m_pDefIPersistStorage->Release();
  93.         }
  94.  
  95.     ReleaseInterface(m_pIAdvSinkView);
  96.     ReleaseInterface(m_pDefIUnknown)
  97.  
  98.     DeleteInterfaceImp(m_pImpIAdviseSink);
  99.     DeleteInterfaceImp(m_pImpIPersistStorage);
  100.     DeleteInterfaceImp(m_pImpIViewObject2);
  101.     DeleteInterfaceImp(m_pImpIOleObject);
  102.  
  103.     return;
  104.     }
  105.  
  106.  
  107.  
  108.  
  109. /*
  110.  * CFigure::Init
  111.  *
  112.  * Purpose:
  113.  *  Performs any intiailization of a CFigure that's prone to failure
  114.  *  that we also use internally before exposing the object outside
  115.  *  this DLL.
  116.  *
  117.  * Parameters:
  118.  *  None
  119.  *
  120.  * Return Value:
  121.  *  BOOL            TRUE if the function is successful,
  122.  *                  FALSE otherwise.
  123.  */
  124.  
  125. BOOL CFigure::Init(void)
  126.     {
  127.     LPUNKNOWN       pIUnknown=this;
  128.     HRESULT         hr;
  129.     DWORD           dwConn;
  130.     FORMATETC       fe;
  131.  
  132.     if (NULL!=m_pUnkOuter)
  133.         pIUnknown=m_pUnkOuter;
  134.  
  135.     //First create our interfaces.
  136.     m_pImpIOleObject=new CImpIOleObject(this, pIUnknown);
  137.  
  138.     if (NULL==m_pImpIOleObject)
  139.         return FALSE;
  140.  
  141.     m_pImpIViewObject2=new CImpIViewObject2(this, pIUnknown);
  142.  
  143.     if (NULL==m_pImpIViewObject2)
  144.         return FALSE;
  145.  
  146.     m_pImpIPersistStorage=new CImpIPersistStorage(this, pIUnknown);
  147.  
  148.     if (NULL==m_pImpIPersistStorage)
  149.         return FALSE;
  150.  
  151.     m_pImpIAdviseSink=new CImpIAdviseSink(this, pIUnknown);
  152.  
  153.     if (NULL==m_pImpIAdviseSink)
  154.         return FALSE;
  155.  
  156.     /*
  157.      * Get an IUnknown on the default handler, passing pIUnknown
  158.      * as the controlling unknown.  The extra reference count is to
  159.      * prevent us from going away accidentally.
  160.      */
  161.     m_cRef++;
  162.  
  163.     hr=OleCreateDefaultHandler(CLSID_CosmoFigure, pIUnknown
  164.         , IID_IUnknown, (PPVOID)&m_pDefIUnknown);
  165.  
  166.     if (FAILED(hr))
  167.         return FALSE;
  168.  
  169.     /*
  170.      * NOTE:  The spec specifically states that any interfaces
  171.      * besides IUnknown that we obtain on an aggregated object
  172.      * should be Released immediately after we QueryInterface for
  173.      * them because the QueryInterface will AddRef us, and since
  174.      * we would not release these interfaces until we were
  175.      * destroyed, we'd never go away because we'd never get a zero
  176.      * ref count.
  177.      */
  178.  
  179.     //Now try to get other interfaces to which we delegate
  180.     hr=m_pDefIUnknown->QueryInterface(IID_IOleObject
  181.         , (PPVOID)&m_pDefIOleObject);
  182.  
  183.     if (FAILED(hr))
  184.         return FALSE;
  185.  
  186.     pIUnknown->Release();
  187.  
  188.     hr=m_pDefIUnknown->QueryInterface(IID_IViewObject2
  189.         , (PPVOID)&m_pDefIViewObject2);
  190.  
  191.     if (FAILED(hr))
  192.         return FALSE;
  193.  
  194.     pIUnknown->Release();
  195.  
  196.     hr=m_pDefIUnknown->QueryInterface(IID_IDataObject
  197.         , (PPVOID)&m_pDefIDataObject);
  198.  
  199.     if (FAILED(hr))
  200.         return FALSE;
  201.  
  202.     pIUnknown->Release();
  203.  
  204.     hr=m_pDefIUnknown->QueryInterface(IID_IPersistStorage
  205.         , (PPVOID)&m_pDefIPersistStorage);
  206.  
  207.     if (FAILED(hr))
  208.         return FALSE;
  209.  
  210.     pIUnknown->Release();
  211.  
  212.     m_cRef--;
  213.  
  214.     //Set up an advise on native data so we can keep in sync
  215.     SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
  216.     m_pDefIDataObject->DAdvise(&fe, 0, m_pImpIAdviseSink, &dwConn);
  217.  
  218.     return TRUE;
  219.     }
  220.  
  221.  
  222.  
  223.  
  224.  
  225. /*
  226.  * CFigure::QueryInterface
  227.  * CFigure::AddRef
  228.  * CFigure::Release
  229.  *
  230.  * Purpose:
  231.  *  IUnknown members for CFigure object.
  232.  */
  233.  
  234. STDMETHODIMP CFigure::QueryInterface(REFIID riid, PPVOID ppv)
  235.     {
  236.     *ppv=NULL;
  237.  
  238.     /*
  239.      * The only calls we get here for IUnknown are either in a non-
  240.      * aggregated case or when we're created in an aggregation, so
  241.      * in either we always return our IUnknown for IID_IUnknown.
  242.      */
  243.     if (IID_IUnknown==riid)
  244.         *ppv=this;
  245.  
  246.     if (IID_IPersist==riid || IID_IPersistStorage==riid)
  247.         *ppv=m_pImpIPersistStorage;
  248.  
  249.     if (IID_IOleObject==riid)
  250.         *ppv=m_pImpIOleObject;
  251.  
  252.     if (IID_IViewObject==riid || IID_IViewObject2==riid)
  253.         *ppv=m_pImpIViewObject2;
  254.  
  255.     if (NULL!=*ppv)
  256.         {
  257.         ((LPUNKNOWN)*ppv)->AddRef();
  258.         return NOERROR;
  259.         }
  260.  
  261.     /*
  262.      * Only expose default handler interfaces that you explicitly
  263.      * know you are aggregating.  You cannot just blindly
  264.      * delegate any other QueryInterface to the handler because
  265.      * it may return interfaces you do not expect...such as a
  266.      * newer version of an interface you implement in the handler.
  267.      * We know as a handler that we must provide IDataObject,
  268.      * IOleCache[2], IOleCacheControl, and IRunnableObject, and
  269.      * these we get from the default handler.
  270.      */
  271.  
  272.     if (IID_IDataObject==riid || IID_IOleCache==riid
  273.         || IID_IOleCache2==riid || IID_IOleCacheControl==riid
  274.         || IID_IRunnableObject==riid)
  275.         return m_pDefIUnknown->QueryInterface(riid, ppv);
  276.  
  277.     return ResultFromScode(E_NOINTERFACE);
  278.     }
  279.  
  280.  
  281. STDMETHODIMP_(ULONG) CFigure::AddRef(void)
  282.     {
  283.     return ++m_cRef;
  284.     }
  285.  
  286.  
  287. STDMETHODIMP_(ULONG) CFigure::Release(void)
  288.     {
  289.     if (0!=--m_cRef)
  290.         return m_cRef;
  291.  
  292.     m_cRef++;
  293.     delete this;
  294.     return 0;
  295.     }
  296.  
  297.  
  298.  
  299.  
  300.  
  301. /*
  302.  * CFigure::Draw
  303.  *
  304.  * Purpose:
  305.  *  Paints the current window to an hDC which might be a printer.
  306.  *
  307.  * Parameters:
  308.  *  hDC             HDC to draw on, could be a metafile or
  309.  *                  printer DC.
  310.  *  pRect           LPRECT defining hDC bounds in which to draw.
  311.  *  dwAspect        DWORD aspect to draw.
  312.  *  ptd             DVTARGETDEVICE * containing device info.
  313.  *  hICDev          HDC containing the IC for the device.
  314.  *  ppl             PPOLYLINEDATA from which to draw.
  315.  *
  316.  * Return Value:
  317.  *  None
  318.  */
  319.  
  320. void CFigure::Draw(HDC hDC, LPRECT pRect, DWORD dwAspect
  321.     , DVTARGETDEVICE *ptd, HDC hICDev, PPOLYLINEDATA ppl)
  322.     {
  323.     HBRUSH          hBrush;
  324.     HPEN            hPen;
  325.     HGDIOBJ         hObj1, hObj2;
  326.     UINT            i, j;
  327.     int             nDC;
  328.     POINTS          pt1,pt2;
  329.     POINT           rgpt[CPOLYLINEPOINTS];
  330.  
  331.     nDC=SaveDC(hDC);
  332.  
  333.     for (i=0; i < ppl->cPoints; i++)
  334.         {
  335.         rgpt[i].x=ppl->rgpt[i].x;
  336.         rgpt[i].y=ppl->rgpt[i].y;
  337.         }
  338.  
  339.     hPen=CreatePen(ppl->iLineStyle, 1, ppl->rgbLine);
  340.     hObj1=SelectObject(hDC, hPen);
  341.  
  342.     hBrush=CreateSolidBrush(ppl->rgbBackground);
  343.     hObj2=SelectObject(hDC, hBrush);
  344.     SetBkColor(hDC, ppl->rgbBackground);
  345.  
  346.     //If we have one point, draw a dot to indicate it's position.
  347.     if (1==m_pl.cPoints)
  348.         {
  349.         pt1.x=(short)rgpt[0].x;
  350.         pt1.y=(short)rgpt[0].y;
  351.         PointScale(pRect, &pt1, TRUE);
  352.         SetPixel(hDC, pt1.x, pt1.y, m_pl.rgbLine);
  353.         }
  354.     else
  355.         {
  356.         //Erase the background for bitmaps and metafiles.
  357.         SelectObject(hDC, GetStockObject(NULL_PEN));
  358.         Rectangle(hDC, pRect->left, pRect->top, pRect->right+1
  359.             , pRect->bottom+1);
  360.         SelectObject(hDC, hPen);
  361.  
  362.         for (i=0; i < ppl->cPoints; i++)
  363.             {
  364.             for (j=i; j < ppl->cPoints; j++)
  365.                 {
  366.                 pt1.x=(short)rgpt[i].x;
  367.                 pt1.y=(short)rgpt[i].y;
  368.                 pt2.x=(short)rgpt[j].x;
  369.                 pt2.y=(short)rgpt[j].y;
  370.                 PointScale(pRect, &pt1, TRUE);
  371.                 PointScale(pRect, &pt2, TRUE);
  372.                 MoveToEx(hDC, pt1.x, pt1.y, NULL);
  373.                 LineTo(hDC, pt2.x, pt2.y);
  374.                 }
  375.             }
  376.         }
  377.  
  378.     SelectObject(hDC, hObj1);
  379.     SelectObject(hDC, hObj2);
  380.     DeleteObject(hBrush);
  381.     DeleteObject(hPen);
  382.  
  383.     RestoreDC(hDC, nDC);
  384.     return;
  385.     }
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393. /*
  394.  * CFIgure::PointScale
  395.  *
  396.  * Purpose:
  397.  *  Scales a point from a 0-32767 coordinate to a rectangle relative
  398.  *  coordinate.
  399.  *
  400.  * Parameters:
  401.  *  pRect           LPRECT in which to scale.
  402.  *  ppt             LPPOINTS to convert
  403.  *  fUnused         BOOL of no use.
  404.  *
  405.  * Return Value:
  406.  *  None
  407.  */
  408.  
  409. void CFigure::PointScale(LPRECT pRect, LPPOINTS ppt, BOOL fUnused)
  410.     {
  411.     DWORD   cx, cy;
  412.  
  413.     cx=(DWORD)(pRect->right-pRect->left);
  414.     cy=(DWORD)(pRect->bottom-pRect->top);
  415.  
  416.     //Must use DWORD to insure proper scaling.
  417.     ppt->x=pRect->left+(UINT)(((DWORD)ppt->x*cx) >> 15);
  418.     ppt->y=pRect->top+(UINT)(((DWORD)ppt->y*cy) >> 15);
  419.  
  420.     return;
  421.     }
  422.