www.pudn.com > VCad3.0.zip > VCadDoc.cpp


// VCadDoc.cpp : implementation of the CVCadDoc class 
// 
 
#include "stdafx.h" 
#include "MainFrm.h" 
#include "VCad.h" 
#include "VCadDoc.h" 
#include "Entity.h" 
#include "VCadView.h" 
#include "Dxf.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadDoc 
 
IMPLEMENT_DYNCREATE(CVCadDoc, CDocument) 
 
BEGIN_MESSAGE_MAP(CVCadDoc, CDocument) 
	//{{AFX_MSG_MAP(CVCadDoc) 
	ON_COMMAND(IDM_SAVE_DXF, OnSaveDxf) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadDoc construction/destruction 
 
CVCadDoc::CVCadDoc() 
{ 
	// TODO: add one-time construction code here 
	g_pDoc = this; 
	m_pPmtEntity = NULL; // 设置处于提示状态的元素为空 
} 
 
CVCadDoc::~CVCadDoc() 
{ 
	 
} 
 
BOOL CVCadDoc::OnNewDocument() 
{ 
	if (!CDocument::OnNewDocument()) 
		return FALSE; 
 
	// TODO: add reinitialization code here 
	// (SDI documents will reuse this document) 
 
	return TRUE; 
} 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadDoc serialization 
 
void CVCadDoc::Serialize(CArchive& ar) 
{ 
	m_EntityList.Serialize(ar); 
	if (ar.IsStoring()) 
	{ 
		// TODO: add storing code here 
	} 
	else 
	{ 
		// TODO: add loading code here 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadDoc diagnostics 
 
#ifdef _DEBUG 
void CVCadDoc::AssertValid() const 
{ 
	CDocument::AssertValid(); 
} 
 
void CVCadDoc::Dump(CDumpContext& dc) const 
{ 
	CDocument::Dump(dc); 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadDoc commands 
void CVCadDoc::Draw(CDC *pDC) 
{ 
	// 绘制链表中的图元 
	POSITION	pos = m_EntityList.GetHeadPosition(); 
	while(pos!=NULL) 
	{ 
		CEntity*	pEntity = (CEntity *) m_EntityList.GetNext(pos); 
		pEntity->Draw(pDC, dmNormal); 
	} 
	// 绘制选择集中的图元 
	for( int i = 0 ; i < m_selectArray.GetSize() ; i++ ){ 
		CEntity*	pSelEntity = (CEntity*) m_selectArray[i] ; 
        pSelEntity->Draw(pDC, dmSelect) ; 
	} 
} 
// 清空选择集 
void CVCadDoc::RemoveAllSelected() 
{ 
	// 首先将选择集中的元素绘制为正常状态,然后清空选择集 
	CDC*	pDC = g_pView->GetDC(); 
	for( int i = 0 ; i < m_selectArray.GetSize() ; i++ ){ 
		CEntity*	pSelEntity = (CEntity*) m_selectArray[i] ; 
        pSelEntity->Draw(pDC, dmNormal) ; 
	} 
	m_selectArray.RemoveAll() ; 
	g_pView->ReleaseDC(pDC); 
} 
// 判断某一图元对象是否被选中 
BOOL CVCadDoc::IsSelected(CEntity* pEntity) 
{ 
	// 判断图元对象是否已经在选择集中 
	if( pEntity ) 
	{ 
		for( int i = 0 ; i < m_selectArray.GetSize() ; i++ ) 
		{ 
			if( pEntity == (CEntity*)m_selectArray[i] ) 
				return TRUE ; 
		} 
	} 
	return FALSE; 
} 
void CVCadDoc::OnMouseMove(UINT nFlags, const Position& pos) 
{ 
	if(m_EntityList.GetCount() == 0) 
		return; 
	::Prompt("拾取一个图元或按Ctrl键拾取多个图元"); 
	BOOL	bPicked = FALSE; 
	CEntity*	pickedEntity = NULL; 
	// 遍历图元链表,判断是否存在图元被拾取到 
	POSITION	position = m_EntityList.GetHeadPosition(); 
	while(position != NULL){ 
		CEntity*	pEntity = (CEntity *)m_EntityList.GetNext(position); 
		// 得到当前状态的拾取半径 
		double curRadius = PICK_RADIUS / g_pView->GetScale();  
		if( pEntity->Pick(pos, curRadius) ){ // 当某一个图元被拾取到后,即退出循环 
			bPicked = TRUE; 
			pickedEntity = pEntity; 
			break; 
		} 
	} 
	CDC*	pDC = g_pView->GetDC(); // 得到视的设备环境指针 
	if( bPicked ){ // 如果某个图元被拾取到 
		// 如果以前存在提示图元 
		// 那么将提示图元对象恢复到正常绘制状态,并设置为空 
		if( m_pPmtEntity ){			 
			m_pPmtEntity->Draw( pDC, dmNormal );  
			m_pPmtEntity = NULL; 
		} 
		// 将拾取到的图元设置为提示图元 
		m_pPmtEntity = pickedEntity ;  
		// 如果提示图元不在选择集中,那么将它高亮显示 
		if( ! IsSelected(m_pPmtEntity) ){  
			//设置光标状态; 
			m_pPmtEntity->LoadPmtCursor(); 
			m_pPmtEntity->Draw( pDC, dmPrompt ); 
		} 
		// 如果提示图元已存在于选择集中,那么将它恢复为空 
		else  
			m_pPmtEntity = NULL; 
	} 
	else{ // 如果没有图元被拾取到 
		// 如果以前存在提示图元 
		// 那么将提示图元对象恢复到正常绘制状态,并设置为空 
		if( m_pPmtEntity ){  
			m_pPmtEntity->Draw( pDC, dmNormal );  
			m_pPmtEntity = NULL; 
		} 
    } 
	g_pView->ReleaseDC(pDC); // 释放视的设备环境指针 
} 
void CVCadDoc::OnLButtonDown(UINT nFlags, const Position& pos) 
{ 
	CDC*	pDC = g_pView->GetDC() ;// 得到视的设备环境指针 
	// 如果存在提示图元,那么当按下鼠标左键时,将该图元加入到选择集中 
	if(m_pPmtEntity){  
		if( !(nFlags & MK_CONTROL) ) // 如果没有按下Ctrl键,则首先清空选择集 
			RemoveAllSelected(); 
		m_pPmtEntity->Draw(pDC,dmSelect); // 将图元绘制为选中状态 
		m_selectArray.Add(m_pPmtEntity);  // 将图元放入选择集中 
	} 
	else{ 
		if( !(nFlags & MK_CONTROL) )// 如果没有按下Ctrl键,则清空选择集 
			RemoveAllSelected(); 
	} 
	m_pPmtEntity = NULL; // 将提示图元对象设置为空 
	g_pView->ReleaseDC(pDC);// 释放视的设备环境指针 
}  
 
void CVCadDoc::DeleteContents()  
{ 
	// TODO: Add your specialized code here and/or call the base class 
    // 清空选择集 
	m_selectArray.RemoveAll(); 
	// 清除图元链表中的图元对象 
	POSITION	pos = m_EntityList.GetHeadPosition(); 
	while(pos!=NULL) 
	{ 
		CEntity*	pEntity = (CEntity *) m_EntityList.GetNext(pos); 
		delete pEntity ; 
	} 
	m_EntityList.RemoveAll() ; 
	 
	CDocument::DeleteContents(); 
} 
 
void CVCadDoc::OnSaveDxf()  
{ 
	// TODO: Add your command handler code here 
	char szFilter[] = "DXF文件(*.DXF)|*.DXF||"; 
	CFileDialog	dlg(FALSE, NULL, NULL, 
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); 
	 
	if(dlg.DoModal() == IDOK){ 
		CString filename = dlg.GetPathName(); 
		if(dlg.GetFileExt() == "") 
			filename += ".dxf"; 
		CDxf	dxf; 
		if(!dxf.OutputDxf(this, filename)){ 
			AfxMessageBox("保存为DXF文件时失败"); 
			return; 
		} 
	}   
}