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

  1. // ContrVw.cpp : implementation of the CContainerView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Contain.h"
  6.  
  7. #include "ContrDoc.h"
  8. #include "CntrItem.h"
  9. #include "ContrVw.h"
  10.  
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CContainerView
  19.  
  20. IMPLEMENT_DYNCREATE(CContainerView, CView)
  21.  
  22. BEGIN_MESSAGE_MAP(CContainerView, CView)
  23.     //{{AFX_MSG_MAP(CContainerView)
  24.         // NOTE - the ClassWizard will add and remove mapping macros here.
  25.         //    DO NOT EDIT what you see in these blocks of generated code!
  26.     ON_WM_SETFOCUS()
  27.     ON_WM_SIZE()
  28.     ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
  29.     ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
  30.     ON_WM_LBUTTONDOWN()
  31.     ON_WM_LBUTTONDBLCLK()
  32.     ON_WM_SETCURSOR()
  33.     ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
  34.     ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear)
  35.     //}}AFX_MSG_MAP
  36.     // Standard printing commands
  37.     ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  38.     ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  39.     ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  40. END_MESSAGE_MAP()
  41.  
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CContainerView construction/destruction
  44.  
  45. CContainerView::CContainerView()
  46. {
  47.     m_pSelection = NULL;
  48.     // TODO: add construction code here
  49.  
  50. }
  51.  
  52. CContainerView::~CContainerView()
  53. {
  54. }
  55.  
  56. BOOL CContainerView::PreCreateWindow(CREATESTRUCT& cs)
  57. {
  58.     // TODO: Modify the Window class or styles here by modifying
  59.     //  the CREATESTRUCT cs
  60.  
  61.     return CView::PreCreateWindow(cs);
  62. }
  63.  
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CContainerView drawing
  66.  
  67. void CContainerView::OnDraw(CDC* pDC)
  68. {
  69.     CContainerDoc* pDoc = GetDocument();
  70.     ASSERT_VALID(pDoc);
  71.  
  72.     // draw the OLE items from the list
  73.     POSITION pos = pDoc->GetStartPosition();
  74.     while (pos != NULL)
  75.     {
  76.         // draw the item
  77.         CContainerItem* pItem = (CContainerItem*)pDoc->GetNextItem(pos);
  78.         pItem->Draw(pDC, pItem->m_rect);
  79.  
  80.         // draw the tracker over the item
  81.         CRectTracker tracker;
  82.         SetupTracker(pItem, &tracker);
  83.         tracker.Draw(pDC);
  84.     }
  85. }
  86.  
  87. void CContainerView::OnInitialUpdate()
  88. {
  89.     CView::OnInitialUpdate();
  90.  
  91.     // TODO: remove this code when final selection model code is written
  92.     m_pSelection = NULL;    // initialize selection
  93.  
  94. }
  95.  
  96. /////////////////////////////////////////////////////////////////////////////
  97. // CContainerView printing
  98.  
  99. BOOL CContainerView::OnPreparePrinting(CPrintInfo* pInfo)
  100. {
  101.     // default preparation
  102.     return DoPreparePrinting(pInfo);
  103. }
  104.  
  105. void CContainerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  106. {
  107.     // TODO: add extra initialization before printing
  108. }
  109.  
  110. void CContainerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  111. {
  112.     // TODO: add cleanup after printing
  113. }
  114.  
  115. /////////////////////////////////////////////////////////////////////////////
  116. // OLE Client support and commands
  117.  
  118. BOOL CContainerView::IsSelected(const CObject* pDocItem) const
  119. {
  120.     // The implementation below is adequate if your selection consists of
  121.     //  only CContainerItem objects.  To handle different selection
  122.     //  mechanisms, the implementation here should be replaced.
  123.  
  124.     // TODO: implement this function that tests for a selected OLE client item
  125.  
  126.     return pDocItem == m_pSelection;
  127. }
  128.  
  129. void CContainerView::OnInsertObject()
  130. {
  131.     // Invoke the standard Insert Object dialog box to obtain information
  132.     //  for new CContainerItem object.
  133.     COleInsertDialog dlg;
  134.     if (dlg.DoModal() != IDOK)
  135.         return;
  136.  
  137.     BeginWaitCursor();
  138.  
  139.     CContainerItem* pItem = NULL;
  140.     TRY
  141.     {
  142.         // Create new item connected to this document.
  143.         CContainerDoc* pDoc = GetDocument();
  144.         ASSERT_VALID(pDoc);
  145.         pItem = new CContainerItem(pDoc);
  146.         ASSERT_VALID(pItem);
  147.  
  148.         // Initialize the item from the dialog data.
  149.         if (!dlg.CreateItem(pItem))
  150.             AfxThrowMemoryException();  // any exception will do
  151.         ASSERT_VALID(pItem);
  152.  
  153.         // If item created from class list (not from file) then launch
  154.         //  the server to edit the item.
  155.         if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
  156.             pItem->DoVerb(OLEIVERB_SHOW, this);
  157.  
  158.         ASSERT_VALID(pItem);
  159.  
  160.         // As an arbitrary user interface design, this sets the selection
  161.         //  to the last item inserted.
  162.  
  163.         // TODO: reimplement selection as appropriate for your application
  164.  
  165.         m_pSelection = pItem;   // set selection to last inserted item
  166.         pDoc->UpdateAllViews(NULL);
  167.     }
  168.     CATCH(CException, e)
  169.     {
  170.         if (pItem != NULL)
  171.         {
  172.             ASSERT_VALID(pItem);
  173.             pItem->Delete();
  174.         }
  175.         AfxMessageBox(IDP_FAILED_TO_CREATE);
  176.     }
  177.     END_CATCH
  178.  
  179.     EndWaitCursor();
  180. }
  181.  
  182. // The following command handler provides the standard keyboard
  183. //  user interface to cancel an in-place editing session.  Here,
  184. //  the container (not the server) causes the deactivation.
  185. void CContainerView::OnCancelEditCntr()
  186. {
  187.     // Close any in-place active item on this view.
  188.     COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  189.     if (pActiveItem != NULL)
  190.     {
  191.         pActiveItem->Close();
  192.     }
  193.     ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
  194. }
  195.  
  196. // Special handling of OnSetFocus and OnSize are required for a container
  197. //  when an object is being edited in-place.
  198. void CContainerView::OnSetFocus(CWnd* pOldWnd)
  199. {
  200.     COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  201.     if (pActiveItem != NULL &&
  202.         pActiveItem->GetItemState() == COleClientItem::activeUIState)
  203.     {
  204.         // need to set focus to this item if it is in the same view
  205.         CWnd* pWnd = pActiveItem->GetInPlaceWindow();
  206.         if (pWnd != NULL)
  207.         {
  208.             pWnd->SetFocus();   // don't call the base class
  209.             return;
  210.         }
  211.     }
  212.  
  213.     CView::OnSetFocus(pOldWnd);
  214. }
  215.  
  216. void CContainerView::OnSize(UINT nType, int cx, int cy)
  217. {
  218.     CView::OnSize(nType, cx, cy);
  219.     COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  220.     if (pActiveItem != NULL)
  221.         pActiveItem->SetItemRects();
  222. }
  223. CContainerItem* CContainerView::HitTestItems(CPoint point)
  224. {
  225.     CContainerDoc* pDoc = GetDocument();
  226.     CContainerItem* pItemHit = NULL;
  227.     POSITION pos = pDoc->GetStartPosition();
  228.     while (pos != NULL)
  229.     {
  230.         CContainerItem* pItem = (CContainerItem*)pDoc->GetNextItem(pos);
  231.         if (pItem->m_rect.PtInRect(point))
  232.             pItemHit = pItem;
  233.     }
  234.     return pItemHit;    // return top item at point
  235. }
  236.  
  237. void CContainerView::SetSelection(CContainerItem* pItem)
  238. {
  239.     // close in-place active item
  240.     if (pItem == NULL || m_pSelection != pItem)
  241.     {
  242.         COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  243.         if (pActiveItem != NULL && pActiveItem != pItem)
  244.             pActiveItem->Close();
  245.     }
  246.     Invalidate();
  247.     m_pSelection = pItem;
  248. }
  249.  
  250. void CContainerView::SetupTracker(CContainerItem* pItem, CRectTracker* pTracker)
  251. {
  252.     pTracker->m_rect = pItem->m_rect;
  253.  
  254.     if (pItem == m_pSelection)
  255.         pTracker->m_nStyle |= CRectTracker::resizeInside;
  256.  
  257.     if (pItem->GetType() == OT_LINK)
  258.         pTracker->m_nStyle |= CRectTracker::dottedLine;
  259.     else
  260.         pTracker->m_nStyle |= CRectTracker::solidLine;
  261.  
  262.     if (pItem->GetItemState() == COleClientItem::openState ||
  263.         pItem->GetItemState() == COleClientItem::activeUIState)
  264.     {
  265.         pTracker->m_nStyle |= CRectTracker::hatchInside;
  266.     }
  267. }
  268.  
  269.  
  270. /////////////////////////////////////////////////////////////////////////////
  271. // CContainerView diagnostics
  272.  
  273. #ifdef _DEBUG
  274. void CContainerView::AssertValid() const
  275. {
  276.     CView::AssertValid();
  277. }
  278.  
  279. void CContainerView::Dump(CDumpContext& dc) const
  280. {
  281.     CView::Dump(dc);
  282. }
  283.  
  284. CContainerDoc* CContainerView::GetDocument() // non-debug version is inline
  285. {
  286.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CContainerDoc)));
  287.     return (CContainerDoc*)m_pDocument;
  288. }
  289. #endif //_DEBUG
  290.  
  291. /////////////////////////////////////////////////////////////////////////////
  292. // CContainerView message handlers
  293. void CContainerView::OnLButtonDown(UINT nFlags, CPoint point)
  294. {
  295.     CContainerItem* pItemHit = HitTestItems(point);
  296.     SetSelection(pItemHit);
  297.  
  298.     if (pItemHit != NULL)
  299.     {
  300.         CRectTracker tracker;
  301.         SetupTracker(pItemHit, &tracker);
  302.  
  303.         UpdateWindow();
  304.         if (tracker.Track(this, point))
  305.         {
  306.             Invalidate();
  307.             pItemHit->m_rect = tracker.m_rect;
  308.             GetDocument()->SetModifiedFlag();
  309.         }
  310.     }
  311.  
  312.     CView::OnLButtonDown(nFlags, point);
  313. }
  314.  
  315. void CContainerView::OnLButtonDblClk(UINT nFlags, CPoint point)
  316. {
  317.     OnLButtonDown(nFlags, point);
  318.  
  319.     if (m_pSelection != NULL)
  320.     {
  321.         m_pSelection->DoVerb(GetKeyState(VK_CONTROL) < 0 ?
  322.             OLEIVERB_OPEN : OLEIVERB_PRIMARY, this);
  323.     }
  324.  
  325.     CView::OnLButtonDblClk(nFlags, point);
  326. }
  327.  
  328. BOOL CContainerView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  329. {
  330.     if (pWnd == this && m_pSelection != NULL)
  331.     {
  332.         // give the tracker for the selection a chance
  333.         CRectTracker tracker;
  334.         SetupTracker(m_pSelection, &tracker);
  335.         if (tracker.SetCursor(this, nHitTest))
  336.             return TRUE;
  337.     }
  338.  
  339.     return CView::OnSetCursor(pWnd, nHitTest, message);
  340. }
  341.  
  342. void CContainerView::OnEditClear()
  343. {
  344.     if (m_pSelection != NULL)
  345.     {
  346.         m_pSelection->Delete();
  347.         m_pSelection = NULL;
  348.         GetDocument()->UpdateAllViews(NULL);
  349.     }
  350. }
  351.  
  352. void CContainerView::OnUpdateEditClear(CCmdUI* pCmdUI)
  353. {
  354.     pCmdUI->Enable(m_pSelection != NULL);
  355.  
  356. }
  357.