home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / oclient / rectitem.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  6.8 KB  |  300 lines

  1. // rectitem.cpp : implementation of the CRectItem class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13.  
  14. #include "stdafx.h"
  15. #include <afxpriv.h>
  16. #include "oclient.h"
  17.  
  18. #include "maindoc.h"
  19. #include "mainview.h"
  20. #include "rectitem.h"
  21.  
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28.  
  29. IMPLEMENT_SERIAL(CRectItem, COleClientItem, 0)
  30.  
  31. CRectItem::CRectItem(COleDocument* pContainer) : COleClientItem(pContainer) ,
  32.     m_ptPos(10, -10), m_sizeContent(0,0), m_sizeIcon(0,0),
  33.     m_sizeContentExtent(0, 0), m_sizeIconExtent(0, 0)
  34. {
  35. }
  36.  
  37. CRectItem::CRectItem() : m_ptPos(10, -10), m_sizeContent(0,0), m_sizeIcon(0,0),
  38.     m_sizeContentExtent(0, 0), m_sizeIconExtent(0, 0)
  39. {
  40. }
  41.  
  42. CRectItem::~CRectItem()
  43. {
  44. }
  45.  
  46. void CRectItem::Invalidate(CView* pNotThisView)
  47. {
  48.     GetDocument()->UpdateAllViews(pNotThisView, 0, this);
  49. }
  50.  
  51. /////////////////////////////////////////////////////////////////////////////
  52.  
  53. CSize CRectItem::GetSize()
  54. {
  55.     DVASPECT dv = GetDrawAspect();
  56.     if (dv == DVASPECT_ICON)
  57.         return m_sizeIcon;
  58.     else
  59.         return m_sizeContent;
  60. }
  61.  
  62. CSize CRectItem::GetBaseSize()
  63. {
  64.     DVASPECT dv = GetDrawAspect();
  65.     if (dv == DVASPECT_ICON)
  66.         return m_sizeIconExtent;
  67.     else
  68.         return m_sizeContentExtent;
  69. }
  70.  
  71. void CRectItem::SetSize(CSize size)
  72. {
  73.     DVASPECT dv = GetDrawAspect();
  74.     if (dv == DVASPECT_ICON)
  75.         m_sizeIcon = size;
  76.     else
  77.         m_sizeContent = size;
  78. }
  79.  
  80. void CRectItem::SetBaseSize(CSize size)
  81. {
  82.     DVASPECT dv = GetDrawAspect();
  83.     if (dv == DVASPECT_ICON)
  84.         m_sizeIconExtent = size;
  85.     else
  86.         m_sizeContentExtent = size;
  87. }
  88.  
  89. void CRectItem::SetRect(CRect& rect)
  90. {
  91.     m_ptPos = rect.TopLeft();
  92.     SetSize(rect.Size());
  93. }
  94.  
  95. BOOL CRectItem::UpdateExtent()
  96. {
  97.     // get size in pixels
  98.     CSize size;
  99.     if (!GetCachedExtent(&size))
  100.         return FALSE;       // blank
  101.     Invalidate();   // invalidate the old size/position
  102.     CSize sizeBase = GetBaseSize();
  103.     if (size == sizeBase) // no change
  104.         return FALSE;
  105.     // if new object (i.e. m_extent is empty) setup position
  106.     if (sizeBase == CSize(0,0))
  107.     {
  108.         // convert to document coords
  109.         CSize sizeNew(MulDiv(size.cx, 10, 254), - MulDiv(size.cy, 10, 254));
  110.         SetSize(sizeNew);
  111.     }
  112.     else
  113.     {
  114.         if (!IsInPlaceActive() && size != sizeBase)
  115.         {
  116.             // data changed and not inplace, so scale up rect as well
  117.             CSize sizeCur = GetSize();
  118.             sizeCur.cx = MulDiv(sizeCur.cx, size.cx, sizeBase.cx);
  119.             sizeCur.cy = - MulDiv(-sizeCur.cy, size.cy, sizeBase.cy);
  120.             SetSize(sizeCur);
  121.         }
  122.     }
  123.     SetBaseSize(size);
  124.     Invalidate();   // as well as the new size/position
  125.     return TRUE;
  126. }
  127.  
  128. BOOL CRectItem::OnChangeItemPosition(const CRect& rectPos)
  129. {
  130.     CMainView* pView = GetActiveView();
  131.     if (pView == NULL)
  132.         return FALSE;
  133.     ASSERT_VALID(pView);
  134.  
  135.     CRect rc = rectPos;
  136.     pView->ClientToDoc(rc);
  137.  
  138.     if (rc != GetRect())
  139.     {
  140.         // invalidate old item
  141.         Invalidate();
  142.         // update to new rectangle
  143.         SetRect(rc);
  144.  
  145.         GetDocument()->SetModifiedFlag();
  146.         CSize sizeExtent;
  147.         GetCachedExtent(&sizeExtent);
  148.         SetBaseSize(sizeExtent);
  149.  
  150.         // and invalidate new
  151.         Invalidate();
  152.     }
  153.     return COleClientItem::OnChangeItemPosition(rectPos);
  154. }
  155.  
  156. void CRectItem::OnActivate()
  157. {
  158.     // allow only one inplace active item per frame
  159.     CMainView* pView = GetActiveView();
  160.     ASSERT_VALID(pView);
  161.     COleClientItem* pItem = GetDocument()->GetInPlaceActiveItem(pView);
  162.     if (pItem != NULL && pItem != this)
  163.         pItem->Close();
  164.  
  165.     COleClientItem::OnActivate();
  166.  
  167.     // set selection to an item when it becomes active
  168.     pView->SetSelection(this);
  169. }
  170.  
  171. void CRectItem::OnDeactivateUI(BOOL bUndoable)
  172. {
  173.     COleClientItem::OnDeactivateUI(bUndoable);
  174.  
  175.     // hide the object if it is not an outside-in object
  176.     DWORD dwMisc = 0;
  177.     m_lpObject->GetMiscStatus(GetDrawAspect(), &dwMisc);
  178.     if (dwMisc & OLEMISC_INSIDEOUT)
  179.         DoVerb(OLEIVERB_HIDE, NULL);
  180. }
  181.  
  182. void CRectItem::OnChange(OLE_NOTIFICATION nCode, DWORD dwParam)
  183. {
  184.     COleClientItem::OnChange(nCode, dwParam);
  185.     switch(nCode)
  186.     {
  187.         case OLE_CHANGED:
  188.             UpdateExtent();
  189.             Invalidate();
  190.             break;
  191.         case OLE_CHANGED_ASPECT:
  192.         case OLE_CHANGED_STATE:
  193.             Invalidate();
  194.             break;
  195.     }
  196. }
  197.  
  198. void CRectItem::OnGetItemPosition(CRect& rPosition)
  199. {
  200.     ASSERT_VALID(this);
  201.  
  202.     if (GetSize() == CSize(0,0))
  203.         UpdateExtent();
  204.  
  205.     // copy m_rect, which is in document coordinates
  206.     rPosition = GetRect();
  207.     CMainView* pView = GetActiveView();
  208.     ASSERT_VALID(pView);
  209.     pView->DocToClient(rPosition);
  210. }
  211.  
  212. void CRectItem::Move(CRect &rc)
  213. {
  214.     // invalidate old rect
  215.     Invalidate();
  216.     // invalidate new
  217.     SetRect(rc);
  218.     Invalidate();
  219.  
  220.     // update item rect when in-place active
  221.     if (IsInPlaceActive())
  222.         SetItemRects();
  223. }
  224.  
  225. void CRectItem::Serialize(CArchive& ar)
  226. {
  227.     CRect rect;
  228.  
  229.     // IMPORTANT: when using "easy" serialize -- call base class FIRST!
  230.     //  (not strictly necessary, but a good idea)
  231.     COleClientItem::Serialize(ar);
  232.  
  233.     // now store/retrieve data specific to CRectItem
  234.     if (ar.IsStoring())
  235.     {
  236.         WORD w = 0x5500;        // magic value
  237.         ar << w << m_ptPos << m_sizeIcon << m_sizeIconExtent <<
  238.             m_sizeContent << m_sizeContentExtent;
  239.     }
  240.     else
  241.     {
  242.         WORD w;
  243.         ar >> w >> m_ptPos >> m_sizeIcon >> m_sizeIconExtent >>
  244.             m_sizeContent >> m_sizeContentExtent;
  245.         if (w != 0x5500)
  246.         {
  247.             TRACE0("Bad magic number in front of an item wnd\n");
  248.             AfxThrowArchiveException(CArchiveException::generic);
  249.         }
  250.     }
  251. }
  252.  
  253. void CRectItem::ResetSize()
  254. {
  255.     ASSERT_VALID(this);
  256.     Invalidate();
  257.     SetBaseSize(CSize(0, 0));
  258.     UpdateExtent();
  259. }
  260.  
  261. // OnGetClipboardData is used by CopyToClipboard and DoDragDrop
  262. COleDataSource* CRectItem::OnGetClipboardData(
  263.     BOOL bIncludeLink, LPPOINT lpOffset, LPSIZE lpSize)
  264. {
  265.     ASSERT_VALID(this);
  266.  
  267.     COleDataSource* pDataSource = new COleDataSource;
  268.     TRY
  269.     {
  270.         GetNativeClipboardData(pDataSource);
  271.         GetClipboardData(pDataSource, bIncludeLink, lpOffset, lpSize);
  272.     }
  273.     CATCH_ALL(e)
  274.     {
  275.         delete pDataSource;
  276.         THROW_LAST();
  277.     }
  278.     END_CATCH_ALL
  279.  
  280.     ASSERT_VALID(pDataSource);
  281.     return pDataSource;
  282. }
  283.  
  284. void CRectItem::GetNativeClipboardData(COleDataSource* pDataSource)
  285. {
  286.     ASSERT_VALID(this);
  287.     ASSERT_VALID(GetDocument());
  288.  
  289.     // Create a shared file and associate a CArchive with it
  290.     CSharedFile file;
  291.     CArchive ar(&file, CArchive::store);
  292.  
  293.     // Serialize selected objects to the archive
  294.     Serialize(ar);
  295.     ar.Close();
  296.     pDataSource->CacheGlobalData(CMainDoc::m_cfPrivate, file.Detach());
  297. }
  298.  
  299. /////////////////////////////////////////////////////////////////////////////
  300.