DRAWDOC.CPP
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:16k
源码类别:

界面编程

开发平台:

Visual C++

  1. // drawdoc.cpp : implementation of the CDrawDoc 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 "drawcli.h"
  14. #include "drawdoc.h"
  15. #include "drawvw.h"
  16. #include "drawobj.h"
  17. #include "cntritem.h"
  18. #include "summpage.h"
  19. #include "statpage.h"
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char BASED_CODE THIS_FILE[] = __FILE__;
  23. #endif
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CDrawDoc
  26. IMPLEMENT_DYNCREATE(CDrawDoc, COleServerDoc)
  27. BEGIN_MESSAGE_MAP(CDrawDoc, COleServerDoc)
  28. //{{AFX_MSG_MAP(CDrawDoc)
  29. ON_COMMAND(ID_VIEW_PAPERCOLOR, OnViewPaperColor)
  30. ON_COMMAND(ID_FILE_SUMMARYINFO, OnFileSummaryInfo)
  31. //}}AFX_MSG_MAP
  32. // Enable default OLE container implementation
  33. ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, COleServerDoc::OnUpdatePasteMenu)
  34. ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK, COleServerDoc::OnUpdatePasteLinkMenu)
  35. ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, COleServerDoc::OnUpdateObjectVerbMenu)
  36. ON_COMMAND(ID_OLE_EDIT_CONVERT, COleServerDoc::OnEditConvert)
  37. ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, COleServerDoc::OnUpdateEditLinksMenu)
  38. ON_COMMAND(ID_OLE_EDIT_LINKS, COleServerDoc::OnEditLinks)
  39. ON_UPDATE_COMMAND_UI(ID_OLE_VERB_FIRST, COleServerDoc::OnUpdateObjectVerbMenu)
  40. // MAPI support
  41. ON_COMMAND(ID_FILE_SEND_MAIL, OnFileSendMail)
  42. ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, OnUpdateFileSendMail)
  43. END_MESSAGE_MAP()
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CDrawDoc construction/destruction
  46. CDrawDoc::CDrawDoc()
  47. {
  48. EnableCompoundFile();
  49. m_nMapMode = MM_ANISOTROPIC;
  50. m_paperColor = RGB(255, 255, 255);
  51. m_pSummInfo = NULL;
  52. ComputePageSize();
  53. }
  54. CDrawDoc::~CDrawDoc()
  55. {
  56. POSITION pos = m_objects.GetHeadPosition();
  57. while (pos != NULL)
  58. delete m_objects.GetNext(pos);
  59. delete m_pSummInfo;
  60. }
  61. BOOL CDrawDoc::OnNewDocument()
  62. {
  63. if (!COleServerDoc::OnNewDocument())
  64. return FALSE;
  65. // reinitialization code
  66. // (SDI documents will reuse this document)
  67. if(m_pSummInfo != NULL)
  68. delete m_pSummInfo;
  69. m_pSummInfo = new CSummInfo;
  70. // Title, Subject, Author, Keywords default to empty string
  71. // Comments, Template, SavedBy default to empty string
  72. // LastSave, LastPrint, EditTime, RevNum default to 0
  73. m_pSummInfo->StartEditTimeCount();
  74. m_pSummInfo->RecordCreateDate();
  75. m_pSummInfo->SetNumPages(1);
  76. // NumWords, NumChars default to 0
  77. m_pSummInfo->SetAppname( _T("DrawCli") );
  78. // Security defaults to 0
  79. return TRUE;
  80. }
  81. BOOL CDrawDoc::OnOpenDocument(LPCTSTR lpszPathName)
  82. {
  83. if( m_pSummInfo != NULL)
  84. delete m_pSummInfo;
  85. m_pSummInfo = new CSummInfo;
  86. m_pSummInfo->StartEditTimeCount();
  87. return COleServerDoc::OnOpenDocument(lpszPathName);
  88. }
  89. BOOL CDrawDoc::OnSaveDocument(LPCTSTR lpszPathName)
  90. {
  91. m_pSummInfo->RecordSaveDate();
  92. m_pSummInfo->IncrRevNum();
  93. m_pSummInfo->SetLastAuthor(m_pSummInfo->GetAuthor());
  94. m_pSummInfo->AddCountToEditTime();
  95. m_pSummInfo->StartEditTimeCount();
  96. return COleServerDoc::OnSaveDocument(lpszPathName);
  97. }
  98. /////////////////////////////////////////////////////////////////////////////
  99. // CDrawDoc serialization
  100. void CDrawDoc::Serialize(CArchive& ar)
  101. {
  102. if (ar.IsStoring())
  103. {
  104. ar << DWORD(m_paperColor);
  105. m_objects.Serialize(ar);
  106. m_pSummInfo->WriteToStorage(m_lpRootStg);
  107. }
  108. else
  109. {
  110. DWORD dwTmp;
  111. ar >> dwTmp;
  112. m_paperColor = COLORREF(dwTmp);
  113. m_objects.Serialize(ar);
  114. m_pSummInfo->ReadFromStorage(m_lpRootStg);
  115. }
  116. // By calling the base class COleServerDoc, we enable serialization
  117. //  of the container document's COleClientItem objects automatically.
  118. COleServerDoc::Serialize(ar);
  119. }
  120. /////////////////////////////////////////////////////////////////////////////
  121. // CDrawDoc implementation
  122. void CDrawDoc::Draw(CDC* pDC, CDrawView* pView)
  123. {
  124. POSITION pos = m_objects.GetHeadPosition();
  125. while( pos != NULL )
  126. {
  127. CDrawObj * pObj = m_objects.GetNext( pos );
  128. pObj->Draw( pDC );
  129. if( pView != NULL
  130. && pView->m_bActive
  131. && ( ! pDC->IsPrinting() )
  132. &&  pView->IsSelected( pObj )
  133. )
  134. pObj->DrawTracker(pDC, CDrawObj::selected);
  135. }
  136. }
  137. void CDrawDoc::Add(CDrawObj* pObj)
  138. {
  139. m_objects.AddTail(pObj);
  140. pObj->m_pDocument = this;
  141. SetModifiedFlag();
  142. }
  143. void CDrawDoc::Remove(CDrawObj* pObj)
  144. {
  145. // Find and remove from document
  146. POSITION pos = m_objects.Find(pObj);
  147. if (pos != NULL)
  148. m_objects.RemoveAt(pos);
  149. // set document modified flag
  150. SetModifiedFlag();
  151. // call remove for each view so that the view can remove from m_selection
  152. pos = GetFirstViewPosition();
  153. while (pos != NULL)
  154. ((CDrawView*)GetNextView(pos))->Remove(pObj);
  155. }
  156. // point is in logical coordinates
  157. CDrawObj* CDrawDoc::ObjectAt(const CPoint& point)
  158. {
  159. CRect rect(point, CSize(1, 1));
  160. POSITION pos = m_objects.GetTailPosition();
  161. while (pos != NULL)
  162. {
  163. CDrawObj* pObj = m_objects.GetPrev(pos);
  164. if (pObj->Intersects(rect))
  165. return pObj;
  166. }
  167. return NULL;
  168. }
  169. void CDrawDoc::ComputePageSize()
  170. {
  171. CSize new_size(850, 1100);  // 8.5" x 11" default
  172. CPrintDialog dlgPrint(FALSE);
  173. if (AfxGetApp()->GetPrinterDeviceDefaults(&dlgPrint.m_pd))
  174. {
  175. // GetPrinterDC returns a HDC so attach it
  176. CDC dc;
  177. HDC hDC = dlgPrint.CreatePrinterDC();
  178. ASSERT(hDC != NULL);
  179. dc.Attach(hDC);
  180. // Get the size of the page in loenglish
  181. new_size.cx =
  182. MulDiv(
  183. ::GetDeviceCaps( dc.m_hDC, HORZSIZE ),
  184. 1000,
  185. 254
  186. );
  187. new_size.cy =
  188. MulDiv(
  189. ::GetDeviceCaps( dc.m_hDC, VERTSIZE ),
  190. 1000,
  191. 254
  192. );
  193. }
  194. // if size changed then iterate over views and reset
  195. if (new_size != m_size)
  196. {
  197. m_size = new_size;
  198. POSITION pos = GetFirstViewPosition();
  199. while (pos != NULL)
  200. ((CDrawView*)GetNextView(pos))->SetPageSize(m_size);
  201. }
  202. }
  203. void CDrawDoc::OnViewPaperColor()
  204. {
  205. CColorDialog dlgColor;
  206. if( dlgColor.DoModal() != IDOK )
  207. return;
  208. m_paperColor = dlgColor.GetColor();
  209. SetModifiedFlag();
  210. UpdateAllViews( NULL );
  211. }
  212. /////////////////////////////////////////////////////////////////////////////
  213. // CDrawDoc diagnostics
  214. #ifdef _DEBUG
  215. void CDrawDoc::AssertValid() const
  216. {
  217. COleServerDoc::AssertValid();
  218. }
  219. void CDrawDoc::Dump(CDumpContext& dc) const
  220. {
  221. COleServerDoc::Dump(dc);
  222. }
  223. #endif //_DEBUG
  224. /////////////////////////////////////////////////////////////////////////////
  225. // CDrawDoc commands
  226. void CDrawDoc::OnFileSummaryInfo()
  227. {
  228. ASSERT_VALID(this);
  229. CPropertySheet sheet( _T("Document Properties") );
  230. CSummPage summ;
  231. CStatPage stat;
  232. sheet.AddPage( &summ );
  233. sheet.AddPage( &stat );
  234. summ.m_strAppname = m_pSummInfo->GetAppname();
  235. summ.m_strTitle   = m_pSummInfo->GetTitle();
  236. summ.m_strSubj    = m_pSummInfo->GetSubject();
  237. summ.m_strAuthor  = m_pSummInfo->GetAuthor();
  238. summ.m_strKeywd   = m_pSummInfo->GetKeywords();
  239. summ.m_strCmt     = m_pSummInfo->GetComments();
  240. summ.m_strTempl   = m_pSummInfo->GetTemplate();
  241. stat.m_strSavedBy    = m_pSummInfo->GetLastAuthor();
  242. stat.m_strRevNum     = m_pSummInfo->GetRevNum();
  243. stat.m_strEditTime   = m_pSummInfo->GetEditTime();
  244. stat.m_strLastPrint  = m_pSummInfo->GetLastPrintDate();
  245. stat.m_strCreateDate = m_pSummInfo->GetCreateDate();
  246. stat.m_strLastSave   = m_pSummInfo->GetLastSaveDate();
  247. stat.m_strNumPages   = m_pSummInfo->GetNumPages();
  248. stat.m_strNumWords   = m_pSummInfo->GetNumWords();
  249. stat.m_strNumChars   = m_pSummInfo->GetNumChars();
  250. stat.m_strSecurity   = m_pSummInfo->GetSecurity();
  251. if (sheet.DoModal() != IDOK)
  252. return;
  253. m_pSummInfo->SetAuthor(summ.m_strAuthor);
  254. m_pSummInfo->SetKeywords(summ.m_strKeywd);
  255. m_pSummInfo->SetSubject(summ.m_strSubj);
  256. m_pSummInfo->SetComments(summ.m_strCmt);
  257. m_pSummInfo->SetTemplate(summ.m_strTempl);
  258. m_pSummInfo->SetTitle(summ.m_strTitle);
  259. SetModifiedFlag();
  260. }
  261. /////////////////////////////////////////////////////////////////////////////
  262. // CDrawDoc server implementation
  263. COleServerItem* CDrawDoc::OnGetEmbeddedItem()
  264. {
  265. // OnGetEmbeddedItem is called by the framework to get the COleServerItem
  266. //  that is associated with the document.  It is only called when necessary.
  267. CDrawSrvrItem* pItem = new CDrawSrvrItem(this);
  268. ASSERT_VALID(pItem);
  269. return pItem;
  270. }
  271. /////////////////////////////////////////////////////////////////////////////
  272. // CDrawCntrItem implementation
  273. IMPLEMENT_SERIAL(CDrawCntrItem, COleClientItem, 0)
  274. CDrawCntrItem::CDrawCntrItem(CDrawDoc* pContainer)
  275. : COleClientItem(pContainer)
  276. {
  277. // TODO: add one-time construction code here
  278. }
  279. CDrawCntrItem::~CDrawCntrItem()
  280. {
  281. // TODO: add cleanup code here
  282. }
  283. void CDrawCntrItem::OnChange(OLE_NOTIFICATION nCode, DWORD dwParam)
  284. {
  285. ASSERT_VALID(this);
  286. COleClientItem::OnChange(nCode, dwParam);
  287. // When an item is being edited (either in-place or fully open)
  288. //  it sends OnChange notifications for changes in the state of the
  289. //  item or visual appearance of its content.
  290. // TODO: invalidate the item by calling UpdateAllViews
  291. //  (with hints appropriate to your application)
  292. GetDocument()->UpdateAllViews(NULL);
  293. // for now just update ALL views/no hints
  294. }
  295. BOOL CDrawCntrItem::OnChangeItemPosition(const CRect& rectPos)
  296. {
  297. ASSERT_VALID(this);
  298. // During in-place activation CDrawCntrItem::OnChangeItemPosition
  299. //  is called by the server to change the position of the in-place
  300. //  window.  Usually, this is a result of the data in the server
  301. //  document changing such that the extent has changed or as a result
  302. //  of in-place resizing.
  303. //
  304. // The default here is to call the base class, which will call
  305. //  COleClientItem::SetItemRects to move the item
  306. //  to the new position.
  307. if (!COleClientItem::OnChangeItemPosition(rectPos))
  308. return FALSE;
  309. // TODO: update any cache you may have of the item's rectangle/extent
  310. return TRUE;
  311. }
  312. void CDrawCntrItem::OnGetItemPosition(CRect& rPosition)
  313. {
  314. ASSERT_VALID(this);
  315. // During in-place activation, CDrawCntrItem::OnGetItemPosition
  316. //  will be called to determine the location of this item.  The default
  317. //  implementation created from AppWizard simply returns a hard-coded
  318. //  rectangle.  Usually, this rectangle would reflect the current
  319. //  position of the item relative to the view used for activation.
  320. //  You can obtain the view by calling CDrawCntrItem::GetActiveView.
  321. // TODO: return correct rectangle (in pixels) in rPosition
  322. rPosition.SetRect(10, 10, 210, 210);
  323. }
  324. void CDrawCntrItem::OnActivate()
  325. {
  326.     // Allow only one inplace activate item per frame
  327.     CDrawView* pView = GetActiveView();
  328.     ASSERT_VALID(pView);
  329.     COleClientItem* pItem = GetDocument()->GetInPlaceActiveItem(pView);
  330.     if (pItem != NULL && pItem != this)
  331.         pItem->Close();
  332.     
  333.     COleClientItem::OnActivate();
  334. }
  335. void CDrawCntrItem::OnDeactivateUI(BOOL bUndoable)
  336. {
  337. COleClientItem::OnDeactivateUI(bUndoable);
  338.     // Hide the object if it is not an outside-in object
  339.     DWORD dwMisc = 0;
  340.     m_lpObject->GetMiscStatus(GetDrawAspect(), &dwMisc);
  341.     if (dwMisc & OLEMISC_INSIDEOUT)
  342.         DoVerb(OLEIVERB_HIDE, NULL);
  343. }
  344. void CDrawCntrItem::Serialize(CArchive& ar)
  345. {
  346. ASSERT_VALID(this);
  347. // Call base class first to read in COleClientItem data.
  348. // Since this sets up the m_pDocument pointer returned from
  349. //  CDrawCntrItem::GetDocument, it is a good idea to call
  350. //  the base class Serialize first.
  351. COleClientItem::Serialize(ar);
  352. // now store/retrieve data specific to CDrawCntrItem
  353. if (ar.IsStoring())
  354. {
  355. // TODO: add storing code here
  356. }
  357. else
  358. {
  359. // TODO: add loading code here
  360. }
  361. }
  362. BOOL CDrawCntrItem::CanActivate()
  363. {
  364. // Editing in-place while the server itself is being edited in-place
  365. //  does not work and is not supported.  So, disable in-place
  366. //  activation in this case.
  367. CDrawDoc* pDoc = GetDocument();
  368. ASSERT_VALID(pDoc);
  369. ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(COleServerDoc)));
  370. if (pDoc->IsInPlaceActive())
  371. return FALSE;
  372. // otherwise, rely on default behavior
  373. return COleClientItem::CanActivate();
  374. }
  375. /////////////////////////////////////////////////////////////////////////////
  376. // CDrawCntrItem diagnostics
  377. #ifdef _DEBUG
  378. void CDrawCntrItem::AssertValid() const
  379. {
  380. COleClientItem::AssertValid();
  381. }
  382. void CDrawCntrItem::Dump(CDumpContext& dc) const
  383. {
  384. COleClientItem::Dump(dc);
  385. }
  386. #endif
  387. /////////////////////////////////////////////////////////////////////////////
  388. // CDrawSrvrItem implementation
  389. IMPLEMENT_DYNAMIC(CDrawSrvrItem, COleServerItem)
  390. CDrawSrvrItem::CDrawSrvrItem(CDrawDoc* pContainerDoc)
  391. : COleServerItem(pContainerDoc, TRUE)
  392. {
  393. // TODO: add one-time construction code here
  394. //  (eg, adding additional clipboard formats to the item's data source)
  395. }
  396. CDrawSrvrItem::~CDrawSrvrItem()
  397. {
  398. // TODO: add cleanup code here
  399. }
  400. void CDrawSrvrItem::Serialize(CArchive& ar)
  401. {
  402. // CDrawSrvrItem::Serialize will be called by the framework if
  403. //  the item is copied to the clipboard.  This can happen automatically
  404. //  through the OLE callback OnGetClipboardData.  A good default for
  405. //  the embedded item is simply to delegate to the document's Serialize
  406. //  function.  If you support links, then you will want to serialize
  407. //  just a portion of the document.
  408. if (!IsLinkedItem())
  409. {
  410. CDrawDoc* pDoc = GetDocument();
  411. ASSERT_VALID(pDoc);
  412. pDoc->Serialize(ar);
  413. }
  414. }
  415. BOOL CDrawSrvrItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
  416. {
  417. // Most applications, like this one, only handle drawing the content
  418. //  aspect of the item.  If you wish to support other aspects, such
  419. //  as DVASPECT_THUMBNAIL (by overriding OnDrawEx), then this
  420. //  implementation of OnGetExtent should be modified to handle the
  421. //  additional aspect(s).
  422. if (dwDrawAspect != DVASPECT_CONTENT)
  423. return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
  424. // CDrawSrvrItem::OnGetExtent is called to get the extent in
  425. //  HIMETRIC units of the entire item.  The default implementation
  426. //  here simply returns a hard-coded number of units.
  427. CDrawDoc* pDoc = GetDocument();
  428. ASSERT_VALID(pDoc);
  429. // TODO: replace this arbitrary size
  430. rSize = CSize(3000, 3000);   // 3000 x 3000 HIMETRIC units
  431. return TRUE;
  432. }
  433. BOOL CDrawSrvrItem::OnDraw(CDC* pDC, CSize& rSize)
  434. {
  435. // Remove this if you use rSize
  436. UNREFERENCED_PARAMETER(rSize);
  437. CDrawDoc* pDoc = GetDocument();
  438. ASSERT_VALID(pDoc);
  439. // TODO: set mapping mode and extent
  440. //  (The extent is usually the same as the size returned from OnGetExtent)
  441. // pDC->SetMapMode(MM_ANISOTROPIC);
  442. // pDC->SetWindowOrg(0,0);
  443. // pDC->SetWindowExt(3000, 3000);
  444. {
  445. pDC->SetMapMode(MM_ANISOTROPIC);
  446. pDC->SetViewportExt(
  447. ::GetDeviceCaps( pDC->m_hDC, LOGPIXELSX ),
  448. ::GetDeviceCaps( pDC->m_hDC, LOGPIXELSY )
  449. );
  450. pDC->SetWindowExt(1000, -1000);
  451. // set the origin of the coordinate system to the center of the page
  452. CSize _sizeDoc = pDoc->GetSize();
  453. _sizeDoc.cx *= 3;
  454. _sizeDoc.cy *= 3;
  455. _sizeDoc.cx /= 2;
  456. _sizeDoc.cy /= 2;
  457. CPoint ptOrg;
  458. ptOrg.x = _sizeDoc.cx / 2;
  459. ptOrg.y = _sizeDoc.cx / 2;
  460. // ptOrg is in logical coordinates
  461. pDC->OffsetWindowOrg(-ptOrg.x,ptOrg.y);
  462. }
  463. // TODO: add drawing code here.  Optionally, fill in the HIMETRIC extent.
  464. //  All drawing takes place in the metafile device context (pDC).
  465. // TODO: also draw embedded CDrawCntrItem objects.
  466. // The following code draws the first item at an arbitrary position.
  467. //  POSITION pos = pDoc->GetStartPosition();
  468. //  CDrawCntrItem* pItem = (CDrawCntrItem*)pDoc->GetNextClientItem(pos);
  469. //  if (pItem != NULL)
  470. //  pItem->Draw(pDC, CRect(10, 10, 1010, 1010));
  471. pDoc->Draw( pDC, NULL );
  472. return TRUE;
  473. }
  474. /////////////////////////////////////////////////////////////////////////////
  475. // CDrawSrvrItem diagnostics
  476. #ifdef _DEBUG
  477. void CDrawSrvrItem::AssertValid() const
  478. {
  479. COleServerItem::AssertValid();
  480. }
  481. void CDrawSrvrItem::Dump(CDumpContext& dc) const
  482. {
  483. COleServerItem::Dump(dc);
  484. }
  485. #endif
  486. /////////////////////////////////////////////////////////////////////////////