home *** CD-ROM | disk | FTP | other *** search
/ Using Visual C++ 4 (Special Edition) / Using_Visual_C_4_Special_Edition_QUE_1996.iso / ch08 / ocontain / contai~2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-10  |  9.9 KB  |  416 lines

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