scribdoc.cpp
上传用户:biuytresa
上传日期:2007-12-07
资源大小:721k
文件大小:8k
源码类别:

DNA

开发平台:

Visual C++

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