DRAWDOC.CPP
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:16k
- // drawdoc.cpp : implementation of the CDrawDoc class
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #include "drawcli.h"
- #include "drawdoc.h"
- #include "drawvw.h"
- #include "drawobj.h"
- #include "cntritem.h"
- #include "summpage.h"
- #include "statpage.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc
- IMPLEMENT_DYNCREATE(CDrawDoc, COleServerDoc)
- BEGIN_MESSAGE_MAP(CDrawDoc, COleServerDoc)
- //{{AFX_MSG_MAP(CDrawDoc)
- ON_COMMAND(ID_VIEW_PAPERCOLOR, OnViewPaperColor)
- ON_COMMAND(ID_FILE_SUMMARYINFO, OnFileSummaryInfo)
- //}}AFX_MSG_MAP
- // Enable default OLE container implementation
- ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, COleServerDoc::OnUpdatePasteMenu)
- ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK, COleServerDoc::OnUpdatePasteLinkMenu)
- ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, COleServerDoc::OnUpdateObjectVerbMenu)
- ON_COMMAND(ID_OLE_EDIT_CONVERT, COleServerDoc::OnEditConvert)
- ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, COleServerDoc::OnUpdateEditLinksMenu)
- ON_COMMAND(ID_OLE_EDIT_LINKS, COleServerDoc::OnEditLinks)
- ON_UPDATE_COMMAND_UI(ID_OLE_VERB_FIRST, COleServerDoc::OnUpdateObjectVerbMenu)
- // MAPI support
- ON_COMMAND(ID_FILE_SEND_MAIL, OnFileSendMail)
- ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, OnUpdateFileSendMail)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc construction/destruction
- CDrawDoc::CDrawDoc()
- {
- EnableCompoundFile();
- m_nMapMode = MM_ANISOTROPIC;
- m_paperColor = RGB(255, 255, 255);
- m_pSummInfo = NULL;
- ComputePageSize();
- }
- CDrawDoc::~CDrawDoc()
- {
- POSITION pos = m_objects.GetHeadPosition();
- while (pos != NULL)
- delete m_objects.GetNext(pos);
- delete m_pSummInfo;
- }
- BOOL CDrawDoc::OnNewDocument()
- {
- if (!COleServerDoc::OnNewDocument())
- return FALSE;
- // reinitialization code
- // (SDI documents will reuse this document)
- if(m_pSummInfo != NULL)
- delete m_pSummInfo;
- m_pSummInfo = new CSummInfo;
- // Title, Subject, Author, Keywords default to empty string
- // Comments, Template, SavedBy default to empty string
- // LastSave, LastPrint, EditTime, RevNum default to 0
- m_pSummInfo->StartEditTimeCount();
- m_pSummInfo->RecordCreateDate();
- m_pSummInfo->SetNumPages(1);
- // NumWords, NumChars default to 0
- m_pSummInfo->SetAppname( _T("DrawCli") );
- // Security defaults to 0
- return TRUE;
- }
- BOOL CDrawDoc::OnOpenDocument(LPCTSTR lpszPathName)
- {
- if( m_pSummInfo != NULL)
- delete m_pSummInfo;
- m_pSummInfo = new CSummInfo;
- m_pSummInfo->StartEditTimeCount();
- return COleServerDoc::OnOpenDocument(lpszPathName);
- }
- BOOL CDrawDoc::OnSaveDocument(LPCTSTR lpszPathName)
- {
- m_pSummInfo->RecordSaveDate();
- m_pSummInfo->IncrRevNum();
- m_pSummInfo->SetLastAuthor(m_pSummInfo->GetAuthor());
- m_pSummInfo->AddCountToEditTime();
- m_pSummInfo->StartEditTimeCount();
- return COleServerDoc::OnSaveDocument(lpszPathName);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc serialization
- void CDrawDoc::Serialize(CArchive& ar)
- {
- if (ar.IsStoring())
- {
- ar << DWORD(m_paperColor);
- m_objects.Serialize(ar);
- m_pSummInfo->WriteToStorage(m_lpRootStg);
- }
- else
- {
- DWORD dwTmp;
- ar >> dwTmp;
- m_paperColor = COLORREF(dwTmp);
- m_objects.Serialize(ar);
- m_pSummInfo->ReadFromStorage(m_lpRootStg);
- }
- // By calling the base class COleServerDoc, we enable serialization
- // of the container document's COleClientItem objects automatically.
- COleServerDoc::Serialize(ar);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc implementation
- void CDrawDoc::Draw(CDC* pDC, CDrawView* pView)
- {
- POSITION pos = m_objects.GetHeadPosition();
- while( pos != NULL )
- {
- CDrawObj * pObj = m_objects.GetNext( pos );
- pObj->Draw( pDC );
- if( pView != NULL
- && pView->m_bActive
- && ( ! pDC->IsPrinting() )
- && pView->IsSelected( pObj )
- )
- pObj->DrawTracker(pDC, CDrawObj::selected);
- }
- }
- void CDrawDoc::Add(CDrawObj* pObj)
- {
- m_objects.AddTail(pObj);
- pObj->m_pDocument = this;
- SetModifiedFlag();
- }
- void CDrawDoc::Remove(CDrawObj* pObj)
- {
- // Find and remove from document
- POSITION pos = m_objects.Find(pObj);
- if (pos != NULL)
- m_objects.RemoveAt(pos);
- // set document modified flag
- SetModifiedFlag();
- // call remove for each view so that the view can remove from m_selection
- pos = GetFirstViewPosition();
- while (pos != NULL)
- ((CDrawView*)GetNextView(pos))->Remove(pObj);
- }
- // point is in logical coordinates
- CDrawObj* CDrawDoc::ObjectAt(const CPoint& point)
- {
- CRect rect(point, CSize(1, 1));
- POSITION pos = m_objects.GetTailPosition();
- while (pos != NULL)
- {
- CDrawObj* pObj = m_objects.GetPrev(pos);
- if (pObj->Intersects(rect))
- return pObj;
- }
- return NULL;
- }
- void CDrawDoc::ComputePageSize()
- {
- CSize new_size(850, 1100); // 8.5" x 11" default
- CPrintDialog dlgPrint(FALSE);
- if (AfxGetApp()->GetPrinterDeviceDefaults(&dlgPrint.m_pd))
- {
- // GetPrinterDC returns a HDC so attach it
- CDC dc;
- HDC hDC = dlgPrint.CreatePrinterDC();
- ASSERT(hDC != NULL);
- dc.Attach(hDC);
- // Get the size of the page in loenglish
- new_size.cx =
- MulDiv(
- ::GetDeviceCaps( dc.m_hDC, HORZSIZE ),
- 1000,
- 254
- );
- new_size.cy =
- MulDiv(
- ::GetDeviceCaps( dc.m_hDC, VERTSIZE ),
- 1000,
- 254
- );
- }
- // if size changed then iterate over views and reset
- if (new_size != m_size)
- {
- m_size = new_size;
- POSITION pos = GetFirstViewPosition();
- while (pos != NULL)
- ((CDrawView*)GetNextView(pos))->SetPageSize(m_size);
- }
- }
- void CDrawDoc::OnViewPaperColor()
- {
- CColorDialog dlgColor;
- if( dlgColor.DoModal() != IDOK )
- return;
- m_paperColor = dlgColor.GetColor();
- SetModifiedFlag();
- UpdateAllViews( NULL );
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc diagnostics
- #ifdef _DEBUG
- void CDrawDoc::AssertValid() const
- {
- COleServerDoc::AssertValid();
- }
- void CDrawDoc::Dump(CDumpContext& dc) const
- {
- COleServerDoc::Dump(dc);
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc commands
- void CDrawDoc::OnFileSummaryInfo()
- {
- ASSERT_VALID(this);
- CPropertySheet sheet( _T("Document Properties") );
- CSummPage summ;
- CStatPage stat;
- sheet.AddPage( &summ );
- sheet.AddPage( &stat );
- summ.m_strAppname = m_pSummInfo->GetAppname();
- summ.m_strTitle = m_pSummInfo->GetTitle();
- summ.m_strSubj = m_pSummInfo->GetSubject();
- summ.m_strAuthor = m_pSummInfo->GetAuthor();
- summ.m_strKeywd = m_pSummInfo->GetKeywords();
- summ.m_strCmt = m_pSummInfo->GetComments();
- summ.m_strTempl = m_pSummInfo->GetTemplate();
- stat.m_strSavedBy = m_pSummInfo->GetLastAuthor();
- stat.m_strRevNum = m_pSummInfo->GetRevNum();
- stat.m_strEditTime = m_pSummInfo->GetEditTime();
- stat.m_strLastPrint = m_pSummInfo->GetLastPrintDate();
- stat.m_strCreateDate = m_pSummInfo->GetCreateDate();
- stat.m_strLastSave = m_pSummInfo->GetLastSaveDate();
- stat.m_strNumPages = m_pSummInfo->GetNumPages();
- stat.m_strNumWords = m_pSummInfo->GetNumWords();
- stat.m_strNumChars = m_pSummInfo->GetNumChars();
- stat.m_strSecurity = m_pSummInfo->GetSecurity();
- if (sheet.DoModal() != IDOK)
- return;
- m_pSummInfo->SetAuthor(summ.m_strAuthor);
- m_pSummInfo->SetKeywords(summ.m_strKeywd);
- m_pSummInfo->SetSubject(summ.m_strSubj);
- m_pSummInfo->SetComments(summ.m_strCmt);
- m_pSummInfo->SetTemplate(summ.m_strTempl);
- m_pSummInfo->SetTitle(summ.m_strTitle);
- SetModifiedFlag();
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc server implementation
- COleServerItem* CDrawDoc::OnGetEmbeddedItem()
- {
- // OnGetEmbeddedItem is called by the framework to get the COleServerItem
- // that is associated with the document. It is only called when necessary.
- CDrawSrvrItem* pItem = new CDrawSrvrItem(this);
- ASSERT_VALID(pItem);
- return pItem;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawCntrItem implementation
- IMPLEMENT_SERIAL(CDrawCntrItem, COleClientItem, 0)
- CDrawCntrItem::CDrawCntrItem(CDrawDoc* pContainer)
- : COleClientItem(pContainer)
- {
- // TODO: add one-time construction code here
-
- }
- CDrawCntrItem::~CDrawCntrItem()
- {
- // TODO: add cleanup code here
-
- }
- void CDrawCntrItem::OnChange(OLE_NOTIFICATION nCode, DWORD dwParam)
- {
- ASSERT_VALID(this);
- COleClientItem::OnChange(nCode, dwParam);
- // When an item is being edited (either in-place or fully open)
- // it sends OnChange notifications for changes in the state of the
- // item or visual appearance of its content.
- // TODO: invalidate the item by calling UpdateAllViews
- // (with hints appropriate to your application)
- GetDocument()->UpdateAllViews(NULL);
- // for now just update ALL views/no hints
- }
- BOOL CDrawCntrItem::OnChangeItemPosition(const CRect& rectPos)
- {
- ASSERT_VALID(this);
- // During in-place activation CDrawCntrItem::OnChangeItemPosition
- // is called by the server to change the position of the in-place
- // window. Usually, this is a result of the data in the server
- // document changing such that the extent has changed or as a result
- // of in-place resizing.
- //
- // The default here is to call the base class, which will call
- // COleClientItem::SetItemRects to move the item
- // to the new position.
- if (!COleClientItem::OnChangeItemPosition(rectPos))
- return FALSE;
- // TODO: update any cache you may have of the item's rectangle/extent
- return TRUE;
- }
- void CDrawCntrItem::OnGetItemPosition(CRect& rPosition)
- {
- ASSERT_VALID(this);
- // During in-place activation, CDrawCntrItem::OnGetItemPosition
- // will be called to determine the location of this item. The default
- // implementation created from AppWizard simply returns a hard-coded
- // rectangle. Usually, this rectangle would reflect the current
- // position of the item relative to the view used for activation.
- // You can obtain the view by calling CDrawCntrItem::GetActiveView.
- // TODO: return correct rectangle (in pixels) in rPosition
- rPosition.SetRect(10, 10, 210, 210);
- }
- void CDrawCntrItem::OnActivate()
- {
- // Allow only one inplace activate item per frame
- CDrawView* pView = GetActiveView();
- ASSERT_VALID(pView);
- COleClientItem* pItem = GetDocument()->GetInPlaceActiveItem(pView);
- if (pItem != NULL && pItem != this)
- pItem->Close();
-
- COleClientItem::OnActivate();
- }
- void CDrawCntrItem::OnDeactivateUI(BOOL bUndoable)
- {
- COleClientItem::OnDeactivateUI(bUndoable);
- // Hide the object if it is not an outside-in object
- DWORD dwMisc = 0;
- m_lpObject->GetMiscStatus(GetDrawAspect(), &dwMisc);
- if (dwMisc & OLEMISC_INSIDEOUT)
- DoVerb(OLEIVERB_HIDE, NULL);
- }
- void CDrawCntrItem::Serialize(CArchive& ar)
- {
- ASSERT_VALID(this);
- // Call base class first to read in COleClientItem data.
- // Since this sets up the m_pDocument pointer returned from
- // CDrawCntrItem::GetDocument, it is a good idea to call
- // the base class Serialize first.
- COleClientItem::Serialize(ar);
- // now store/retrieve data specific to CDrawCntrItem
- if (ar.IsStoring())
- {
- // TODO: add storing code here
- }
- else
- {
- // TODO: add loading code here
- }
- }
- BOOL CDrawCntrItem::CanActivate()
- {
- // Editing in-place while the server itself is being edited in-place
- // does not work and is not supported. So, disable in-place
- // activation in this case.
- CDrawDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(COleServerDoc)));
- if (pDoc->IsInPlaceActive())
- return FALSE;
- // otherwise, rely on default behavior
- return COleClientItem::CanActivate();
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawCntrItem diagnostics
- #ifdef _DEBUG
- void CDrawCntrItem::AssertValid() const
- {
- COleClientItem::AssertValid();
- }
- void CDrawCntrItem::Dump(CDumpContext& dc) const
- {
- COleClientItem::Dump(dc);
- }
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CDrawSrvrItem implementation
- IMPLEMENT_DYNAMIC(CDrawSrvrItem, COleServerItem)
- CDrawSrvrItem::CDrawSrvrItem(CDrawDoc* pContainerDoc)
- : COleServerItem(pContainerDoc, TRUE)
- {
- // TODO: add one-time construction code here
- // (eg, adding additional clipboard formats to the item's data source)
- }
- CDrawSrvrItem::~CDrawSrvrItem()
- {
- // TODO: add cleanup code here
- }
- void CDrawSrvrItem::Serialize(CArchive& ar)
- {
- // CDrawSrvrItem::Serialize will be called by the framework if
- // the item is copied to the clipboard. This can happen automatically
- // through the OLE callback OnGetClipboardData. A good default for
- // the embedded item is simply to delegate to the document's Serialize
- // function. If you support links, then you will want to serialize
- // just a portion of the document.
- if (!IsLinkedItem())
- {
- CDrawDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->Serialize(ar);
- }
- }
- BOOL CDrawSrvrItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
- {
- // Most applications, like this one, only handle drawing the content
- // aspect of the item. If you wish to support other aspects, such
- // as DVASPECT_THUMBNAIL (by overriding OnDrawEx), then this
- // implementation of OnGetExtent should be modified to handle the
- // additional aspect(s).
- if (dwDrawAspect != DVASPECT_CONTENT)
- return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
- // CDrawSrvrItem::OnGetExtent is called to get the extent in
- // HIMETRIC units of the entire item. The default implementation
- // here simply returns a hard-coded number of units.
- CDrawDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // TODO: replace this arbitrary size
- rSize = CSize(3000, 3000); // 3000 x 3000 HIMETRIC units
- return TRUE;
- }
- BOOL CDrawSrvrItem::OnDraw(CDC* pDC, CSize& rSize)
- {
- // Remove this if you use rSize
- UNREFERENCED_PARAMETER(rSize);
- CDrawDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // TODO: set mapping mode and extent
- // (The extent is usually the same as the size returned from OnGetExtent)
- // pDC->SetMapMode(MM_ANISOTROPIC);
- // pDC->SetWindowOrg(0,0);
- // pDC->SetWindowExt(3000, 3000);
- {
- pDC->SetMapMode(MM_ANISOTROPIC);
- pDC->SetViewportExt(
- ::GetDeviceCaps( pDC->m_hDC, LOGPIXELSX ),
- ::GetDeviceCaps( pDC->m_hDC, LOGPIXELSY )
- );
- pDC->SetWindowExt(1000, -1000);
- // set the origin of the coordinate system to the center of the page
- CSize _sizeDoc = pDoc->GetSize();
- _sizeDoc.cx *= 3;
- _sizeDoc.cy *= 3;
- _sizeDoc.cx /= 2;
- _sizeDoc.cy /= 2;
- CPoint ptOrg;
- ptOrg.x = _sizeDoc.cx / 2;
- ptOrg.y = _sizeDoc.cx / 2;
- // ptOrg is in logical coordinates
- pDC->OffsetWindowOrg(-ptOrg.x,ptOrg.y);
- }
- // TODO: add drawing code here. Optionally, fill in the HIMETRIC extent.
- // All drawing takes place in the metafile device context (pDC).
- // TODO: also draw embedded CDrawCntrItem objects.
- // The following code draws the first item at an arbitrary position.
- // POSITION pos = pDoc->GetStartPosition();
- // CDrawCntrItem* pItem = (CDrawCntrItem*)pDoc->GetNextClientItem(pos);
- // if (pItem != NULL)
- // pItem->Draw(pDC, CRect(10, 10, 1010, 1010));
- pDoc->Draw( pDC, NULL );
-
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawSrvrItem diagnostics
- #ifdef _DEBUG
- void CDrawSrvrItem::AssertValid() const
- {
- COleServerItem::AssertValid();
- }
- void CDrawSrvrItem::Dump(CDumpContext& dc) const
- {
- COleServerItem::Dump(dc);
- }
- #endif
- /////////////////////////////////////////////////////////////////////////////