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;
}
}
}