home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / ctlview.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  9KB  |  357 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFXCTL_CORE2_SEG
  14. #pragma code_seg(AFXCTL_CORE2_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // COleControl overridables for IViewObject implementation
  26.  
  27. BOOL COleControl::OnGetColorSet(DVTARGETDEVICE*, HDC, LPLOGPALETTE*)
  28. {
  29.     // Can be overridden by subclass
  30.     return FALSE;
  31. }
  32.  
  33. BOOL COleControl::OnGetViewExtent(DWORD dwDrawAspect, LONG /* lindex */,
  34.     DVTARGETDEVICE* /* ptd */, LPSIZEL lpsizel)
  35. {
  36.     // Can be overridden by subclass for two-pass drawing
  37.     if (dwDrawAspect == DVASPECT_OPAQUE || dwDrawAspect == DVASPECT_TRANSPARENT)
  38.         dwDrawAspect = DVASPECT_CONTENT;
  39.     return SUCCEEDED(m_xOleObject.GetExtent(dwDrawAspect, lpsizel));
  40. }
  41.  
  42. BOOL COleControl::OnGetViewRect(DWORD dwAspect, LPRECTL pRect)
  43. {
  44.     // Can be overridden by subclass for two-pass drawing
  45.     SIZEL size;
  46.     OnGetViewExtent(dwAspect, -1, NULL, &size);
  47.     pRect->left = 0;
  48.     pRect->top = 0;
  49.     pRect->right = size.cx;
  50.     pRect->bottom = -size.cy;
  51.     return TRUE;
  52. }
  53.  
  54. DWORD COleControl::OnGetViewStatus()
  55. {
  56.     // Can be overridden by subclass for two-pass drawing
  57.     return VIEWSTATUS_OPAQUE;
  58. }
  59.  
  60. BOOL COleControl::OnQueryHitPoint(DWORD dwAspect, LPCRECT /* pRectBounds */,
  61.     POINT /* ptlLoc */, LONG /* lCloseHint */, DWORD* pHitResult)
  62. {
  63.     // Can be overridden by subclass for non-rectangular hit-testing
  64.     if (dwAspect == DVASPECT_CONTENT)
  65.     {
  66.         *pHitResult = HITRESULT_HIT;
  67.         return TRUE;
  68.     }
  69.     else
  70.     {
  71.         return FALSE;
  72.     }
  73. }
  74.  
  75. BOOL COleControl::OnQueryHitRect(DWORD dwAspect, LPCRECT /* pRectBounds */,
  76.     LPCRECT /* prcLoc */, LONG /* lCloseHint */, DWORD* pHitResult)
  77. {
  78.     // Can be overridden by subclass for non-rectangular hit-testing
  79.     if (dwAspect == DVASPECT_CONTENT)
  80.     {
  81.         *pHitResult = HITRESULT_HIT;
  82.         return TRUE;
  83.     }
  84.     else
  85.     {
  86.         return FALSE;
  87.     }
  88. }
  89.  
  90. BOOL COleControl::OnGetNaturalExtent(DWORD /* dwAspect */, LONG /* lindex */,
  91.     DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */,
  92.     DVEXTENTINFO* /* pExtentInfo */, LPSIZEL /* psizel */)
  93. {
  94.     // Can be overridden by subclass to provide sizing hints
  95.     return FALSE;
  96. }
  97.  
  98. /////////////////////////////////////////////////////////////////////////////
  99. // COleControl::XViewObject
  100.  
  101. STDMETHODIMP_(ULONG) COleControl::XViewObject::AddRef()
  102. {
  103.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  104.     return (ULONG)pThis->ExternalAddRef();
  105. }
  106.  
  107. STDMETHODIMP_(ULONG) COleControl::XViewObject::Release()
  108. {
  109.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  110.     return (ULONG)pThis->ExternalRelease();
  111. }
  112.  
  113. STDMETHODIMP COleControl::XViewObject::QueryInterface(
  114.     REFIID iid, LPVOID* ppvObj)
  115. {
  116.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  117.     return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  118. }
  119.  
  120.  
  121. STDMETHODIMP COleControl::XViewObject::Draw(DWORD dwDrawAspect, LONG lindex,
  122.     void* pvAspect, DVTARGETDEVICE* ptd, HDC hicTargetDev, HDC hdcDraw,
  123.     LPCRECTL lprcBounds, LPCRECTL lprcWBounds,
  124.     BOOL (CALLBACK* pfnContinue)(DWORD), DWORD dwContinue)
  125. {
  126.     METHOD_PROLOGUE_EX(COleControl, ViewObject)
  127.  
  128.     HRESULT hResult = S_OK;
  129.  
  130.     CRect rc;
  131.  
  132.     if (lprcBounds == NULL)
  133.     {
  134.         if (pThis->m_bInPlaceSiteWndless)
  135.             rc.CopyRect(pThis->m_rcPos);
  136.         else
  137.             return E_INVALIDARG;
  138.     }
  139.     else
  140.     {
  141.         rc.SetRect((int)lprcBounds->left, (int)lprcBounds->top,
  142.             (int)lprcBounds->right, (int)lprcBounds->bottom);
  143.     }
  144.  
  145.     // Check if optimized drawing is permitted
  146.     if (pvAspect != NULL && (pThis->GetControlFlags() & canOptimizeDraw))
  147.     {
  148.         pThis->m_bOptimizedDraw = (((DVASPECTINFO*)pvAspect)->dwFlags &
  149.             DVASPECTINFOFLAG_CANOPTIMIZE);
  150.     }
  151.  
  152.     AfxLockTempMaps();
  153.  
  154.     // Convert from rectangle from logical to device coordinates,
  155.     // save DC state, and switch to MM_TEXT mode.  After drawing,
  156.     // restore DC state.
  157.  
  158.     switch (dwDrawAspect)
  159.     {
  160.     case DVASPECT_CONTENT:
  161.         if (GetDeviceCaps(hdcDraw, TECHNOLOGY) == DT_METAFILE)
  162.         {
  163.             // If attributes DC is NULL, create one, based on ptd.
  164.             HDC hAttribDC = hicTargetDev;
  165.             if (hicTargetDev == NULL)
  166.                 hAttribDC = ::_AfxOleCreateDC(ptd);
  167.  
  168.             // Draw into the metafile DC.
  169.             CMetaFileDC dc;
  170.             dc.Attach(hdcDraw);
  171.             dc.SetAttribDC(hAttribDC);
  172.  
  173.             pThis->DrawMetafile(&dc, rc);
  174.  
  175.             dc.SetAttribDC(NULL);
  176.             dc.Detach();
  177.  
  178.             // If we created an attributes DC, delete it now.
  179.             if (hicTargetDev == NULL)
  180.                 ::DeleteDC(hAttribDC);
  181.         }
  182.         else
  183.         {
  184.             CDC* pDC = CDC::FromHandle(hdcDraw);
  185.             pThis->DrawContent(pDC, rc);
  186.         }
  187.         break;
  188.  
  189.     default:
  190.         if (pThis->m_pDefIViewObject == NULL)
  191.             pThis->m_pDefIViewObject =
  192.                 (LPVIEWOBJECT)pThis->QueryDefHandler(IID_IViewObject);
  193.  
  194.         if (pThis->m_pDefIViewObject != NULL)
  195.         {
  196.             hResult = pThis->m_pDefIViewObject->Draw(
  197.                 dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw,
  198.                 lprcBounds, lprcWBounds, pfnContinue, dwContinue);
  199.         }
  200.     }
  201.  
  202.     AfxUnlockTempMaps();
  203.     pThis->m_bOptimizedDraw = FALSE;
  204.     return hResult;
  205. }
  206.  
  207. STDMETHODIMP COleControl::XViewObject::GetColorSet(DWORD dwDrawAspect,
  208.     LONG lindex, void*, DVTARGETDEVICE* ptd, HDC hicTargetDev,
  209.     LPLOGPALETTE* ppColorSet)
  210. {
  211.     METHOD_PROLOGUE_EX(COleControl, ViewObject)
  212.  
  213.     HRESULT hr = E_FAIL;
  214.  
  215.     if ((dwDrawAspect == DVASPECT_CONTENT) && (lindex == -1) &&
  216.         pThis->OnGetColorSet(ptd, hicTargetDev, ppColorSet))
  217.     {
  218.         hr = S_OK;
  219.     }
  220.  
  221.     return hr;
  222. }
  223.  
  224. STDMETHODIMP COleControl::XViewObject::Freeze(DWORD, LONG, void*, DWORD*)
  225. {
  226.     return E_NOTIMPL;
  227. }
  228.  
  229. STDMETHODIMP COleControl::XViewObject::Unfreeze(DWORD)
  230. {
  231.     return E_NOTIMPL;
  232. }
  233.  
  234. STDMETHODIMP COleControl::XViewObject::SetAdvise(DWORD aspects, DWORD advf,
  235.                     LPADVISESINK pAdvSink)
  236. {
  237.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  238.  
  239.     _AFXCTL_ADVISE_INFO** ppAdviseInfo = &pThis->m_pAdviseInfo;
  240.  
  241.     // Allocate space for advise info, if necessary.
  242.     if (*ppAdviseInfo == NULL)
  243.     {
  244.         TRY
  245.             *ppAdviseInfo = new _AFXCTL_ADVISE_INFO;
  246.         END_TRY
  247.  
  248.         if (*ppAdviseInfo == NULL)
  249.             return E_OUTOFMEMORY;
  250.     }
  251.  
  252.     _AFXCTL_ADVISE_INFO* pAdviseInfo = *ppAdviseInfo;
  253.  
  254.     // Release previous sink, if any.
  255.     if (pAdviseInfo->m_pAdvSink != NULL)
  256.         pAdviseInfo->m_pAdvSink->Release();
  257.  
  258.     // Store new advise info.
  259.     pAdviseInfo->m_dwAspects = aspects;
  260.     pAdviseInfo->m_dwAdvf = advf;
  261.     pAdviseInfo->m_pAdvSink = pAdvSink;
  262.     if (pAdvSink != NULL)
  263.         pAdvSink->AddRef();
  264.  
  265.     return S_OK;
  266. }
  267.  
  268. STDMETHODIMP COleControl::XViewObject::GetAdvise(DWORD* pAspects, DWORD* pAdvf,
  269.     LPADVISESINK* ppAdvSink)
  270. {
  271.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  272.  
  273.     _AFXCTL_ADVISE_INFO* pAdviseInfo = pThis->m_pAdviseInfo;
  274.  
  275.     if ((pAdviseInfo != NULL) && (pAdviseInfo->m_pAdvSink != NULL))
  276.     {
  277.         if (pAspects != NULL)
  278.             *pAspects = pAdviseInfo->m_dwAspects;
  279.  
  280.         if (pAdvf != NULL)
  281.             *pAdvf = pAdviseInfo->m_dwAdvf;
  282.  
  283.         if (ppAdvSink != NULL)
  284.         {
  285.             *ppAdvSink = pAdviseInfo->m_pAdvSink;
  286.             if (*ppAdvSink != NULL)
  287.                 (*ppAdvSink)->AddRef();
  288.         }
  289.     }
  290.     else
  291.     {
  292.         if (pAspects != NULL)
  293.             *pAspects = 0;
  294.  
  295.         if (pAdvf != NULL)
  296.             *pAdvf = 0;
  297.  
  298.         if (ppAdvSink != NULL)
  299.             *ppAdvSink = NULL;
  300.     }
  301.  
  302.     return S_OK;
  303. }
  304.  
  305. STDMETHODIMP COleControl::XViewObject::GetExtent(DWORD dwDrawAspect,
  306.     LONG lindex, DVTARGETDEVICE* ptd, LPSIZEL lpsizel)
  307. {
  308.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  309.     return pThis->OnGetViewExtent(dwDrawAspect, lindex, ptd, lpsizel) ? S_OK :
  310.         E_FAIL;
  311. }
  312.  
  313. STDMETHODIMP COleControl::XViewObject::GetRect(DWORD dwAspect, LPRECTL pRect)
  314. {
  315.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  316.     return pThis->OnGetViewRect(dwAspect, pRect) ? S_OK : DV_E_DVASPECT;
  317. }
  318.  
  319. STDMETHODIMP COleControl::XViewObject::GetViewStatus(DWORD* pdwStatus)
  320. {
  321.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  322.     *pdwStatus = pThis->OnGetViewStatus();
  323.     return S_OK;
  324. }
  325.  
  326. STDMETHODIMP COleControl::XViewObject::QueryHitPoint(DWORD dwAspect,
  327.     LPCRECT pRectBounds, POINT ptlLoc, LONG lCloseHint, DWORD* pHitResult)
  328. {
  329.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  330.     return pThis->OnQueryHitPoint(dwAspect, pRectBounds, ptlLoc, lCloseHint,
  331.         pHitResult) ? S_OK : E_FAIL;
  332. }
  333.  
  334. STDMETHODIMP COleControl::XViewObject::QueryHitRect(DWORD dwAspect,
  335.     LPCRECT pRectBounds, LPCRECT prcLoc, LONG lCloseHint, DWORD* pHitResult)
  336. {
  337.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  338.     return pThis->OnQueryHitRect(dwAspect, pRectBounds, prcLoc, lCloseHint,
  339.         pHitResult) ? S_OK : E_FAIL;
  340. }
  341.  
  342. STDMETHODIMP COleControl::XViewObject::GetNaturalExtent(DWORD dwAspect,
  343.     LONG lindex, DVTARGETDEVICE* ptd, HDC hicTargetDev,
  344.     DVEXTENTINFO* pExtentInfo, LPSIZEL psizel)
  345. {
  346.     METHOD_PROLOGUE_EX_(COleControl, ViewObject)
  347.     return pThis->OnGetNaturalExtent(dwAspect, lindex, ptd, hicTargetDev,
  348.         pExtentInfo, psizel) ? S_OK : E_NOTIMPL;
  349. }
  350.  
  351. /////////////////////////////////////////////////////////////////////////////
  352. // Force any extra compiler-generated code into AFX_INIT_SEG
  353.  
  354. #ifdef AFX_INIT_SEG
  355. #pragma code_seg(AFX_INIT_SEG)
  356. #endif
  357.