Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

363 lines
9.0 KiB

// drawdoc.cpp : implementation of the CDrawDoc class
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1993 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and Microsoft
// QuickHelp and/or WinHelp documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include <afxpriv.h>
#include <afx.h>
#include "SepEdt.h"
#include "drawdoc.h"
#include "drawvw.h"
#include "drawobj.h"
#include "cntritem.h"
#include "mainfrm.h"
#include "textbox.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDrawDoc
IMPLEMENT_DYNCREATE(CDrawDoc, COleDocument)
BEGIN_MESSAGE_MAP(CDrawDoc, COleDocument)
//{{AFX_MSG_MAP(CDrawDoc)
ON_COMMAND(ID_VIEW_PAPERCOLOR, OnViewPaperColor)
//}}AFX_MSG_MAP
// Enable default OLE container implementation
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, COleDocument::OnUpdatePasteMenu)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK, COleDocument::OnUpdatePasteLinkMenu)
ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, COleDocument::OnUpdateEditLinksMenu)
ON_COMMAND(ID_OLE_EDIT_LINKS, COleDocument::OnEditLinks)
ON_UPDATE_COMMAND_UI(ID_OLE_VERB_FIRST, COleDocument::OnUpdateObjectVerbMenu)
ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, COleDocument::OnUpdateObjectVerbMenu)
ON_COMMAND(ID_OLE_EDIT_CONVERT, COleDocument::OnEditConvert)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDrawDoc construction/destruction
CDrawDoc::CDrawDoc()
{
m_nMapMode = MM_ANISOTROPIC;
m_paperColor = RGB(255, 255, 255);
ComputePageSize();
}
CDrawDoc::~CDrawDoc()
{
POSITION pos = m_objects.GetHeadPosition();
while (pos != NULL)
delete m_objects.GetNext(pos);
}
BOOL CDrawDoc::OnNewDocument()
{
CloseEdit();
if (!COleDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
m_nMapMode = MM_ANISOTROPIC;
m_paperColor = RGB(255, 255, 255);
ComputePageSize();
return TRUE;
}
BOOL CDrawDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
CloseEdit();
return COleDocument::OnOpenDocument(lpszPathName);
}
BOOL CDrawDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
CloseEdit();
return COleDocument::OnSaveDocument(lpszPathName);
}
void CDrawDoc::OnCloseDocument()
{
CloseEdit();
COleDocument::OnCloseDocument();
}
void CDrawDoc::CloseEdit()
{
CMainFrame* pframe=(CMainFrame*)(AfxGetMainWnd());
if (pframe==NULL) return;
CDrawView* pview=(CDrawView*)(pframe->GetActiveView());
if (pview==NULL) return;
pview->CloseEdit();
}
/////////////////////////////////////////////////////////////////////////////
// CDrawDoc serialization
void CDrawDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// Save non-text objects into EMF format for printing
if (!StoreForPrinting(ar))
{
// write empty header
SEPFILEHEADER header;
memset(&header, 0, sizeof(SEPFILEHEADER));
ar.Write(&header, sizeof(SEPFILEHEADER));
}
// Save other document contents
ar << m_paperColor;
m_objects.Serialize(ar);
}
else
{
// skip the spooler-time structure
CFile* pfile = ar.GetFile();
if (pfile == NULL) return;
SEPFILEHEADER header;
pfile -> Read(&header, sizeof(SEPFILEHEADER));
pfile -> Seek(header.dwEmfSize + header.dwTextRecords * sizeof(TEXTBOX), CFile::current);
// get the visual objects
ar >> m_paperColor;
m_objects.Serialize(ar);
}
// By calling the base class COleDocument, we enable serialization
// of the container document's COleClientItem objects automatically.
COleDocument::Serialize(ar);
}
BOOL CDrawDoc::StoreForPrinting(CArchive& ar)
{
// setting up EMF DC, using default printer as reference
HDC hPrt = ((CDrawApp*)AfxGetApp()) -> GetDefaultPrinterIC() ;
if (!hPrt) return FALSE;
RECT rect={0, 0, GetDeviceCaps(hPrt,HORZSIZE)*100, GetDeviceCaps(hPrt,VERTSIZE)*100};
CDC dc;
if (! (dc.m_hDC = CreateEnhMetaFile(hPrt, NULL, &rect, NULL))) return FALSE;
dc.SetAttribDC(dc.m_hDC);
// recording meta file
POSITION pos = GetFirstViewPosition();
CDrawView* pView = (CDrawView*)GetNextView(pos);
if (pView == NULL) return FALSE;
CDrawView::m_IsRecording = TRUE;
pView -> OnPrepareDC(&dc, NULL);
Draw(&dc, pView);
CDrawView::m_IsRecording = FALSE;
HENHMETAFILE hEmf = CloseEnhMetaFile(dc.m_hDC);
// storing EMF into archive
DWORD size = GetEnhMetaFileBits(hEmf, NULL, NULL);
if (size == 0) return FALSE;
HGLOBAL hglobal = GlobalAlloc(GMEM_MOVEABLE, size);
if (hglobal == NULL) return FALSE;
LPBYTE buf = (LPBYTE)GlobalLock(hglobal);
if (buf == NULL) return FALSE;
if (GetEnhMetaFileBits(hEmf,size,buf) != size) return FALSE;
SEPFILEHEADER header;
// set EMF size (header)
header.dwEmfSize = size;
// get text objects count
pos = m_objects.GetHeadPosition();
DWORD count=0;
while (pos != NULL)
{
CDrawText* pObj = (CDrawText*)(m_objects.GetNext(pos));
if (pObj->GetLogFontCopy() != NULL)
count++;
}
// set text records (header)
header.dwTextRecords = count;
// set page size (in logical) (header)
header.sizePage = GetSize();
// write header
ar.Write(&header,sizeof(SEPFILEHEADER));
// write EMF into archive
ar.Write(buf, size);
GlobalUnlock(hglobal);
GlobalFree(hglobal);
DeleteEnhMetaFile(hEmf);
// Save text objects for job-info realization and printing
// write text records into archive
pos = m_objects.GetHeadPosition();
while (pos != NULL)
{
CDrawText* pObj = (CDrawText*)(m_objects.GetNext(pos));
LOGFONT *plf;
if ((plf=pObj->GetLogFontCopy()) != NULL) // is text object
{
TEXTBOX tbox;
tbox.position = pObj->m_position;
tbox.color = pObj->m_color;
tbox.align = pObj->m_align;
tbox.lf = pObj->m_lf;
strncpy(tbox.text,pObj->m_text,SEPMAXTEXT);
ar.Write(&tbox,sizeof(TEXTBOX));
}
}
return TRUE;
}
void CDrawDoc::DeleteContents()
{
COleDocument::DeleteContents();
// delete current content and do reinit (not necessary in MDI using new window)
POSITION pos = m_objects.GetHeadPosition();
while (pos != NULL)
delete m_objects.GetNext(pos);
m_objects.RemoveAll();
if ((pos = GetFirstViewPosition())==NULL) return;
((CDrawView*)GetNextView(pos))->m_selection.RemoveAll(); // remove selection
}
/////////////////////////////////////////////////////////////////////////////
// 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->m_bActive && !pDC->IsPrinting() &&
pView->IsSelected(pObj) && !CDrawView::m_IsRecording)
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 //====
HDC hIC;
if (hIC = ((CDrawApp*)AfxGetApp()) -> GetDefaultPrinterIC())
{
CDC dc;
dc.Attach(hIC);
// Get the size of the page in loenglish
new_size.cx = MulDiv(dc.GetDeviceCaps(HORZSIZE), 1000, 254); //====
new_size.cy = MulDiv(dc.GetDeviceCaps(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 dlg;
if (dlg.DoModal() != IDOK)
return;
CWindowDC dc(AfxGetMainWnd());
m_paperColor = dc.GetNearestColor(dlg.GetColor()); // get nearest physical color
// modify color for active edit
POSITION pos=GetFirstViewPosition();
CDrawView* pView=(CDrawView*)GetNextView(pos);
if (pView->m_pedit)
{
delete pView->m_peditbrush;
pView->m_peditbrush = new CBrush;
pView->m_peditbrush->CreateSolidBrush(m_paperColor);
}
SetModifiedFlag();
UpdateAllViews(NULL);
}
/////////////////////////////////////////////////////////////////////////////
// CDrawDoc diagnostics
#ifdef _DEBUG
void CDrawDoc::AssertValid() const
{
COleDocument::AssertValid();
}
void CDrawDoc::Dump(CDumpContext& dc) const
{
COleDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDrawDoc commands