home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / bindscrb / scribdoc.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  8KB  |  319 lines

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