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 / chap21 / polyline / iviewobj.cpp < prev    next >
C/C++ Source or Header  |  1996-05-28  |  11KB  |  410 lines

  1. /*
  2.  * IVIEWOBJ.CPP
  3.  * Polyline Component Chapter 21
  4.  *
  5.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  6.  *
  7.  * Kraig Brockschmidt, Microsoft
  8.  * Internet  :  kraigb@microsoft.com
  9.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  10.  */
  11.  
  12.  
  13. #include "polyline.h"
  14.  
  15.  
  16. /*
  17.  * CImpIViewObject::CImpIViewObject
  18.  * CImpIViewObject::~CImpIViewObject
  19.  *
  20.  * Parameters (Constructor):
  21.  *  pObj            PCPolyline of the object we're in.
  22.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  23.  */
  24.  
  25. CImpIViewObject::CImpIViewObject(PCPolyline pObj
  26.     , LPUNKNOWN pUnkOuter)
  27.     {
  28.     m_cRef=0;
  29.     m_pObj=pObj;
  30.     m_pUnkOuter=pUnkOuter;
  31.     return;
  32.     }
  33.  
  34. CImpIViewObject::~CImpIViewObject(void)
  35.     {
  36.     return;
  37.     }
  38.  
  39.  
  40.  
  41.  
  42. /*
  43.  * CImpIViewObject::QueryInterface
  44.  * CImpIViewObject::AddRef
  45.  * CImpIViewObject::Release
  46.  *
  47.  * Purpose:
  48.  *  IUnknown members for CImpIViewObject object.
  49.  */
  50.  
  51. STDMETHODIMP CImpIViewObject::QueryInterface(REFIID riid, PPVOID ppv)
  52.     {
  53.     return m_pUnkOuter->QueryInterface(riid, ppv);
  54.     }
  55.  
  56.  
  57. STDMETHODIMP_(ULONG) CImpIViewObject::AddRef(void)
  58.     {
  59.     ++m_cRef;
  60.     return m_pUnkOuter->AddRef();
  61.     }
  62.  
  63. STDMETHODIMP_(ULONG) CImpIViewObject::Release(void)
  64.     {
  65.     --m_cRef;
  66.     return m_pUnkOuter->Release();
  67.     }
  68.  
  69.  
  70.  
  71. /*
  72.  * CImpIViewObject::Draw
  73.  *
  74.  * Purpose:
  75.  *  Draws the object on the given hDC specifically for the requested
  76.  *  aspect, device, and within the appropriate bounds.
  77.  *
  78.  * Parameters:
  79.  *  dwAspect        DWORD aspect to draw.
  80.  *  lindex          LONG index of the piece to draw.
  81.  *  pvAspect        LPVOID for extra information, always NULL.
  82.  *  ptd             DVTARGETDEVICE * containing device
  83.  *                  information.
  84.  *  hICDev          HDC containing the IC for the device.
  85.  *  hDC             HDC on which to draw.
  86.  *  pRectBounds     LPCRECTL describing the rectangle in which
  87.  *                  to draw.
  88.  *  pRectWBounds    LPCRECTL describing the placement rectangle
  89.  *                  if part of what you draw is another metafile.
  90.  *  pfnContinue     Function to call periodically during
  91.  *                  long repaints.
  92.  *  dwContinue      DWORD extra information to pass to the
  93.  *                  pfnContinue.
  94.  *
  95.  * Return Value:
  96.  *  HRESULT         NOERROR or a general error value.
  97.  */
  98.  
  99. STDMETHODIMP CImpIViewObject::Draw(DWORD dwAspect, LONG lindex
  100.     , LPVOID pvAspect, DVTARGETDEVICE *ptd, HDC hICDev
  101.     , HDC hDC, LPCRECTL pRectBounds, LPCRECTL pRectWBounds
  102.     , BOOL (CALLBACK *pfnContinue) (DWORD), DWORD dwContinue)
  103.     {
  104.     RECT            rc;
  105.     POLYLINEDATA    pl;
  106.     PPOLYLINEDATA   ppl=&m_pObj->m_pl;
  107.  
  108.     RECTFROMRECTL(rc, *pRectBounds);
  109.  
  110.     //Delegate iconic and printed representations.
  111.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  112.         {
  113.         return m_pObj->m_pDefIViewObject->Draw(dwAspect, lindex
  114.             , pvAspect, ptd, hICDev, hDC, pRectBounds, pRectWBounds
  115.             , pfnContinue, dwContinue);
  116.         }
  117.  
  118.  
  119.     /*
  120.      * If we're asked to draw a frozen aspect, use the data from
  121.      * a copy we made in IViewObject::Freeze.  Otherwise use the
  122.      * current data.
  123.      */
  124.     if (dwAspect & m_pObj->m_dwFrozenAspects)
  125.         {
  126.         //Point to the data to actually use.
  127.         if (DVASPECT_CONTENT==dwAspect)
  128.             ppl=&m_pObj->m_plContent;
  129.         else
  130.             ppl=&m_pObj->m_plThumbnail;
  131.         }
  132.  
  133.  
  134.     //Make a copy so we can modify it (and not worry about threads)
  135.     memcpy(&pl, ppl, CBPOLYLINEDATA);
  136.  
  137.     /*
  138.      * If we're going to a printer, check if it's color capable.
  139.      * if not, then use black on white for this figure.
  140.      */
  141.     if (NULL!=hICDev)
  142.         {
  143.         if (GetDeviceCaps(hICDev, NUMCOLORS) <= 2)
  144.             {
  145.             pl.rgbBackground=RGB(255, 255, 255);
  146.             pl.rgbLine=RGB(0, 0, 0);
  147.             }
  148.         }
  149.  
  150.     m_pObj->Draw(hDC, FALSE, TRUE, &rc, &pl);
  151.     return NOERROR;
  152.     }
  153.  
  154.  
  155.  
  156.  
  157. /*
  158.  * CImpIViewObject::GetColorSet
  159.  *
  160.  * Purpose:
  161.  *  Retrieves the color palette used by the object.
  162.  *
  163.  * Parameters:
  164.  *  dwAspect        DWORD aspect of interest.
  165.  *  lindex          LONG piece of interest.
  166.  *  pvAspect        LPVOID with extra information, always NULL.
  167.  *  ptd             DVTARGETDEVICE * containing device info.
  168.  *  hICDev          HDC containing the IC for the device.
  169.  *  ppColorSet      LPLOGPALETTE * into which to return the
  170.  *                  pointer to the palette in this color set.
  171.  *
  172.  * Return Value:
  173.  *  HRESULT         NOERROR or a general error value.
  174.  */
  175.  
  176. STDMETHODIMP CImpIViewObject::GetColorSet(DWORD dwDrawAspect
  177.     , LONG lindex, LPVOID pvAspect, DVTARGETDEVICE *ptd
  178.     , HDC hICDev, LPLOGPALETTE *ppColorSet)
  179.     {
  180.     return ResultFromScode(E_NOTIMPL);
  181.     }
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188. /*
  189.  * CImpIViewObject::Freeze
  190.  *
  191.  * Purpose:
  192.  *  Freezes the view of a particular aspect such that data
  193.  *  changes do not affect the view.
  194.  *
  195.  * Parameters:
  196.  *  dwAspect        DWORD aspect to freeze.
  197.  *  lindex          LONG piece index under consideration.
  198.  *  pvAspect        LPVOID for further information, always NULL.
  199.  *  pdwFreeze       LPDWORD in which to return the key.
  200.  *
  201.  * Return Value:
  202.  *  HRESULT         NOERROR or a general error value.
  203.  */
  204.  
  205. STDMETHODIMP CImpIViewObject::Freeze(DWORD dwAspect, LONG lindex
  206.     , LPVOID pvAspect, LPDWORD pdwFreeze)
  207.     {
  208.     //Delegate anything for ICON or DOCPRINT aspects
  209.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  210.         {
  211.         return m_pObj->m_pDefIViewObject->Freeze(dwAspect, lindex
  212.             , pvAspect, pdwFreeze);
  213.         }
  214.  
  215.     if (dwAspect & m_pObj->m_dwFrozenAspects)
  216.         {
  217.         *pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
  218.         return ResultFromScode(VIEW_S_ALREADY_FROZEN);
  219.         }
  220.  
  221.     m_pObj->m_dwFrozenAspects |= dwAspect;
  222.  
  223.  
  224.     /*
  225.      * For whatever aspects become frozen, make a copy of the data.
  226.      * Later when drawing, if such a frozen aspect is requested,
  227.      * we'll draw from this data rather than from our current data.
  228.      */
  229.     if (DVASPECT_CONTENT & dwAspect)
  230.         {
  231.         memcpy(&m_pObj->m_plContent, &m_pObj->m_pl
  232.             , CBPOLYLINEDATA);
  233.         }
  234.  
  235.     if (DVASPECT_THUMBNAIL & dwAspect)
  236.         {
  237.         memcpy(&m_pObj->m_plThumbnail, &m_pObj->m_pl
  238.             , CBPOLYLINEDATA);
  239.         }
  240.  
  241.     if (NULL!=pdwFreeze)
  242.         *pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
  243.  
  244.     return NOERROR;
  245.     }
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252. /*
  253.  * CImpIViewObject::Unfreeze
  254.  *
  255.  * Purpose:
  256.  *  Thaws an aspect frozen in ::Freeze.  We expect that a container
  257.  *  will redraw us after freezing if necessary, so we don't send
  258.  *  any sort of notification here.
  259.  *
  260.  * Parameters:
  261.  *  dwFreeze        DWORD key returned from ::Freeze.
  262.  *
  263.  * Return Value:
  264.  *  HRESULT         NOERROR or a general error value.
  265.  */
  266.  
  267. STDMETHODIMP CImpIViewObject::Unfreeze(DWORD dwFreeze)
  268.     {
  269.     DWORD       dwAspect=dwFreeze - FREEZE_KEY_OFFSET;
  270.  
  271.     //Delegate anything for ICON or DOCPRINT aspects
  272.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  273.         m_pObj->m_pDefIViewObject->Unfreeze(dwFreeze);
  274.  
  275.     //The aspect to unfreeze is in the key.
  276.     m_pObj->m_dwFrozenAspects &= ~(dwAspect);
  277.  
  278.     /*
  279.      * Since we always kept our current data up to date, we don't
  280.      * have to do anything thing here like requesting data again.
  281.      * Because we removed dwAspect from m_dwFrozenAspects, Draw
  282.      * will again use the current data.
  283.      */
  284.  
  285.     return NOERROR;
  286.     }
  287.  
  288.  
  289.  
  290.  
  291.  
  292. /*
  293.  * CImpIViewObject::SetAdvise
  294.  *
  295.  * Purpose:
  296.  *  Provides an advise sink to the view object enabling
  297.  *  notifications for a specific aspect.
  298.  *
  299.  * Parameters:
  300.  *  dwAspects       DWORD describing the aspects of interest.
  301.  *  dwAdvf          DWORD containing advise flags.
  302.  *  pIAdviseSink    LPADVISESINK to notify.
  303.  *
  304.  * Return Value:
  305.  *  HRESULT         NOERROR or a general error value.
  306.  */
  307.  
  308. STDMETHODIMP CImpIViewObject::SetAdvise(DWORD dwAspects, DWORD dwAdvf
  309.     , LPADVISESINK pIAdviseSink)
  310.     {
  311.     //Pass anything with DVASPECT_ICON or _DOCPRINT to the handler.
  312.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspects))
  313.         {
  314.         m_pObj->m_pDefIViewObject->SetAdvise(dwAspects, dwAdvf
  315.             , pIAdviseSink);
  316.         }
  317.  
  318.     //We continue because dwAspects may have more than one in it.
  319.     if (NULL!=m_pObj->m_pIAdviseSink)
  320.         m_pObj->m_pIAdviseSink->Release();
  321.  
  322.     m_pObj->m_pIAdviseSink=pIAdviseSink;
  323.     m_pObj->m_dwAdviseAspects=dwAspects;
  324.     m_pObj->m_dwAdviseFlags=dwAdvf;
  325.  
  326.     if (NULL!=m_pObj->m_pIAdviseSink)
  327.         m_pObj->m_pIAdviseSink->AddRef();
  328.  
  329.     return NOERROR;
  330.     }
  331.  
  332.  
  333.  
  334.  
  335. /*
  336.  * CImpIViewObject::GetAdvise
  337.  *
  338.  * Purpose:
  339.  *  Returns the last known IAdviseSink seen by ::SetAdvise.
  340.  *
  341.  * Parameters:
  342.  *  pdwAspects      LPDWORD in which to store the last
  343.  *                  requested aspects.
  344.  *  pdwAdvf         LPDWORD in which to store the last
  345.  *                  requested flags.
  346.  *  ppIAdvSink      LPADVISESINK * in which to store the
  347.  *                  IAdviseSink.
  348.  *
  349.  * Return Value:
  350.  *  HRESULT         NOERROR or a general error value.
  351.  */
  352.  
  353. STDMETHODIMP CImpIViewObject::GetAdvise(LPDWORD pdwAspects
  354.     , LPDWORD pdwAdvf, LPADVISESINK *ppAdvSink)
  355.     {
  356.     if (NULL!=ppAdvSink)
  357.         {
  358.         *ppAdvSink=m_pObj->m_pIAdviseSink;
  359.         m_pObj->m_pIAdviseSink->AddRef();
  360.         }
  361.  
  362.     if (NULL!=pdwAspects)
  363.         *pdwAspects=m_pObj->m_dwAdviseAspects;
  364.  
  365.     if (NULL!=pdwAdvf)
  366.         *pdwAdvf=m_pObj->m_dwAdviseFlags;
  367.  
  368.     return NOERROR;
  369.     }
  370.  
  371.  
  372.  
  373.  
  374. /*
  375.  * CImpIViewObject::GetExtent
  376.  *
  377.  * Purpose:
  378.  *  Retrieves the extents of the object's display.
  379.  *
  380.  * Parameters:
  381.  *  dwAspect        DWORD of the aspect of interest.
  382.  *  lindex          LONG index of the piece of interest.
  383.  *  ptd             DVTARGETDEVICE * with device information.
  384.  *  pszl            LPSIZEL to the structure in which to return
  385.  *                  the extents.
  386.  *
  387.  * Return Value:
  388.  *  HRESULT         NOERROR or a general error value.
  389.  */
  390.  
  391. STDMETHODIMP CImpIViewObject::GetExtent(DWORD dwAspect, LONG lindex
  392.     , DVTARGETDEVICE *ptd, LPSIZEL pszl)
  393.     {
  394.     RECT            rc;
  395.  
  396.     if (!(DVASPECT_CONTENT & dwAspect))
  397.         {
  398.         return m_pObj->m_pDefIViewObject->GetExtent(dwAspect
  399.             , lindex, ptd, pszl);
  400.         }
  401.  
  402.     m_pObj->m_pImpIPolyline->RectGet(&rc);
  403.     m_pObj->RectConvertMappings(&rc, FALSE);
  404.  
  405.     pszl->cx=rc.right-rc.left;
  406.     pszl->cy=rc.bottom-rc.top;
  407.  
  408.     return NOERROR;
  409.     }
  410.