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 / iviewobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  11.2 KB  |  433 lines

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