home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / SCRIB7.PAK / SCRIBDOC.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  7.5 KB  |  305 lines

  1. // ScribDoc.cpp : implementation of the CScribbleDoc class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1995 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. #include "stdafx.h"
  14. #include "Scribble.h"
  15.  
  16. #include "ScribDoc.h"
  17. #include "ScribItm.h"
  18. #include "PenDlg.h"
  19. #include "ScribVw.h"
  20.  
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CScribbleDoc
  29.  
  30. IMPLEMENT_DYNCREATE(CScribbleDoc, COleServerDoc)
  31.  
  32. BEGIN_MESSAGE_MAP(CScribbleDoc, COleServerDoc)
  33.     //{{AFX_MSG_MAP(CScribbleDoc)
  34.     ON_COMMAND(ID_EDIT_CLEAR_ALL, OnEditClearAll)
  35.     ON_COMMAND(ID_PEN_THICK_OR_THIN, OnPenThickOrThin)
  36.     ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR_ALL, OnUpdateEditClearAll)
  37.     ON_UPDATE_COMMAND_UI(ID_PEN_THICK_OR_THIN, OnUpdatePenThickOrThin)
  38.     ON_COMMAND(ID_PEN_WIDTHS, OnPenWidths)
  39.     ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  40.     //}}AFX_MSG_MAP
  41. END_MESSAGE_MAP()
  42.  
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CScribbleDoc construction/destruction
  45.  
  46. CScribbleDoc::CScribbleDoc()
  47. {
  48.     // Use OLE compound files
  49.     EnableCompoundFile();
  50.  
  51.     m_sizeDoc = CSize(200, 200);
  52. }
  53.  
  54. CScribbleDoc::~CScribbleDoc()
  55. {
  56. }
  57.  
  58. BOOL CScribbleDoc::OnNewDocument()
  59. {
  60.     if (!COleServerDoc::OnNewDocument())
  61.         return FALSE;
  62.     InitDocument();
  63.     return TRUE;
  64. }
  65.  
  66. /////////////////////////////////////////////////////////////////////////////
  67. // CScribbleDoc serialization
  68.  
  69. void CScribbleDoc::Serialize(CArchive& ar)
  70. {
  71.     if (ar.IsStoring())
  72.     {
  73.         ar << m_sizeDoc;
  74.     }
  75.     else
  76.     {
  77.         ar >> m_sizeDoc;
  78.     }
  79.     m_strokeList.Serialize(ar);
  80. }
  81.  
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CScribbleDoc diagnostics
  84.  
  85. #ifdef _DEBUG
  86. void CScribbleDoc::AssertValid() const
  87. {
  88.     COleServerDoc::AssertValid();
  89. }
  90.  
  91. void CScribbleDoc::Dump(CDumpContext& dc) const
  92. {
  93.     COleServerDoc::Dump(dc);
  94. }
  95. #endif //_DEBUG
  96.  
  97. /////////////////////////////////////////////////////////////////////////////
  98. // CScribbleDoc commands
  99.  
  100. BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName) 
  101. {
  102.     if (!COleServerDoc::OnOpenDocument(lpszPathName))
  103.         return FALSE;
  104.     InitDocument(); 
  105.     return TRUE;
  106. }
  107.  
  108. void CScribbleDoc::DeleteContents() 
  109. {
  110.     while (!m_strokeList.IsEmpty())
  111.     {
  112.         delete m_strokeList.RemoveHead();
  113.     }
  114.     COleServerDoc::DeleteContents();
  115. }
  116.  
  117. void CScribbleDoc::InitDocument()
  118. {
  119.     m_bThickPen = FALSE;
  120.     m_nThinWidth = 2;   // default thin pen is 2 pixels wide
  121.     m_nThickWidth = 5;  // default thick pen is 5 pixels wide
  122.     ReplacePen();       // initialize pen according to current width
  123.  
  124.     // default document size is 2 x 2 inches
  125.     m_sizeDoc = CSize(200,200);
  126. }
  127.  
  128. CStroke* CScribbleDoc::NewStroke()
  129. {
  130.     CStroke* pStrokeItem = new CStroke(m_nPenWidth);
  131.     m_strokeList.AddTail(pStrokeItem);
  132.     SetModifiedFlag();  // Mark the document as having been modified, for
  133.                         // purposes of confirming File Close.
  134.     return pStrokeItem;
  135. }
  136.  
  137.  
  138.  
  139.  
  140. /////////////////////////////////////////////////////////////////////////////
  141. // CStroke
  142.  
  143. IMPLEMENT_SERIAL(CStroke, CObject, 2)
  144. CStroke::CStroke()
  145. {
  146.     // This empty constructor should be used by serialization only
  147. }
  148.  
  149. CStroke::CStroke(UINT nPenWidth)
  150. {
  151.     m_nPenWidth = nPenWidth;
  152.     m_rectBounding.SetRectEmpty();
  153. }
  154.  
  155. void CStroke::Serialize(CArchive& ar)
  156. {
  157.     if (ar.IsStoring())
  158.     {
  159.         ar << m_rectBounding;
  160.         ar << (WORD)m_nPenWidth;
  161.         m_pointArray.Serialize(ar);
  162.     }
  163.     else
  164.     {
  165.         ar >> m_rectBounding;
  166.         WORD w;
  167.         ar >> w;
  168.         m_nPenWidth = w;
  169.         m_pointArray.Serialize(ar);
  170.     }
  171. }
  172.  
  173. BOOL CStroke::DrawStroke(CDC* pDC)
  174. {
  175.     CPen penStroke;
  176.     if (!penStroke.CreatePen(PS_SOLID, m_nPenWidth, RGB(0,0,0)))
  177.         return FALSE;
  178.     CPen* pOldPen = pDC->SelectObject(&penStroke);
  179.     pDC->MoveTo(m_pointArray[0]);
  180.     for (int i=1; i < m_pointArray.GetSize(); i++)
  181.     {
  182.         pDC->LineTo(m_pointArray[i]);
  183.     }
  184.  
  185.     pDC->SelectObject(pOldPen);
  186.     return TRUE;
  187. }
  188. void CScribbleDoc::OnEditClearAll() 
  189. {
  190.     DeleteContents();
  191.     SetModifiedFlag();  // Mark the document as having been modified, for
  192.                         // purposes of confirming File Close.
  193.     UpdateAllViews(NULL);
  194. }
  195.  
  196. void CScribbleDoc::OnPenThickOrThin() 
  197. {
  198.     // Toggle the state of the pen between thin or thick.
  199.     m_bThickPen = !m_bThickPen;
  200.  
  201.     // Change the current pen to reflect the new user-specified width.
  202.     ReplacePen();
  203. }
  204.  
  205. void CScribbleDoc::ReplacePen()
  206. {
  207.     m_nPenWidth = m_bThickPen? m_nThickWidth : m_nThinWidth;
  208.  
  209.     // Change the current pen to reflect the new user-specified width.
  210.     m_penCur.DeleteObject();
  211.     m_penCur.CreatePen(PS_SOLID, m_nPenWidth, RGB(0,0,0)); // solid black
  212. }
  213.  
  214. void CScribbleDoc::OnUpdateEditClearAll(CCmdUI* pCmdUI) 
  215. {
  216.     // Enable the command user interface object (menu item or tool bar
  217.     // button) if the document is non-empty, i.e., has at least one stroke.
  218.     pCmdUI->Enable(!m_strokeList.IsEmpty());
  219. }
  220.  
  221. void CScribbleDoc::OnUpdatePenThickOrThin(CCmdUI* pCmdUI) 
  222. {
  223.     // Add check mark to Draw Thick Line menu item, if the current
  224.     // pen width is "thick".
  225.     pCmdUI->SetCheck(m_bThickPen);
  226. }
  227.  
  228. void CScribbleDoc::OnPenWidths() 
  229. {
  230.     CPenWidthsDlg dlg;
  231.     // Initialize dialog data
  232.     dlg.m_nThinWidth = m_nThinWidth;
  233.     dlg.m_nThickWidth = m_nThickWidth;
  234.  
  235.     // Invoke the dialog box
  236.     if (dlg.DoModal() == IDOK)
  237.     {
  238.         // retrieve the dialog data
  239.         m_nThinWidth = dlg.m_nThinWidth;
  240.         m_nThickWidth = dlg.m_nThickWidth;
  241.  
  242.         // Update the pen that is used by views when drawing new strokes,
  243.         // to reflect the new pen width definitions for "thick" and "thin".
  244.         ReplacePen();
  245.     }
  246. }
  247.  
  248. void CStroke::FinishStroke()
  249. {
  250.     // Calculate the bounding rectangle.  It's needed for smart
  251.     // repainting.
  252.  
  253.     if (m_pointArray.GetSize()==0)
  254.     {
  255.         m_rectBounding.SetRectEmpty();
  256.         return;
  257.     }
  258.     CPoint pt = m_pointArray[0];
  259.     m_rectBounding = CRect(pt.x, pt.y, pt.x, pt.y);
  260.  
  261.     for (int i=1; i < m_pointArray.GetSize(); i++)
  262.     {
  263.         // If the point lies outside of the accumulated bounding
  264.         // rectangle, then inflate the bounding rect to include it.
  265.         pt = m_pointArray[i];
  266.         m_rectBounding.left     = min(m_rectBounding.left, pt.x);
  267.         m_rectBounding.right    = max(m_rectBounding.right, pt.x);
  268.         m_rectBounding.top      = max(m_rectBounding.top, pt.y);
  269.         m_rectBounding.bottom   = min(m_rectBounding.bottom, pt.y);
  270.     }
  271.  
  272.     // Add the pen width to the bounding rectangle.  This is necessary
  273.     // to account for the width of the stroke when invalidating
  274.     // the screen.
  275.     m_rectBounding.InflateRect(CSize(m_nPenWidth, -(int)m_nPenWidth));
  276.     return;
  277. }
  278.  
  279. COleServerItem* CScribbleDoc::OnGetEmbeddedItem()
  280. {
  281.     // OnGetEmbeddedItem is called by the framework to get the COleServerItem
  282.     //  that is associated with the document.  It is only called when necessary.
  283.  
  284.     CScribbleItem* pItem = new CScribbleItem(this);
  285.     ASSERT_VALID(pItem);
  286.     return pItem;
  287. }
  288.  
  289. void CScribbleDoc::OnSetItemRects(LPCRECT lpPosRect, LPCRECT lpClipRect)
  290. {
  291.     // call base class to change the size of the window
  292.     COleServerDoc::OnSetItemRects(lpPosRect, lpClipRect);
  293.  
  294.     // notify first view that scroll info should change
  295.     POSITION pos = GetFirstViewPosition();
  296.     CScribbleView* pView = (CScribbleView*)GetNextView(pos);
  297.     pView->ResyncScrollSizes();
  298. }
  299.  
  300. void CScribbleDoc::OnEditCopy()
  301. {
  302.     CScribbleItem* pItem = GetEmbeddedItem();
  303.     pItem->CopyToClipboard(TRUE);
  304. }
  305.