www.pudn.com > huicad.rar > VCADVIEW.CPP


// VCadView.cpp : implementation of the CVCadView class 
// 
 
#include "stdafx.h" 
#include "VCad.h" 
#include "math.h" 
#include "VCadDoc.h" 
#include "VCadView.h" 
#include "MainFrm.h" 
#include "Base.h" 
#include "Command.h" 
#include "CreateCmd.h" 
#include "ModifyCmd.h" 
#include "ChgViewCmd.h" 
#include "Entity.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadView 
 
IMPLEMENT_DYNCREATE(CVCadView, CView) 
 
BEGIN_MESSAGE_MAP(CVCadView, CView) 
	//{{AFX_MSG_MAP(CVCadView) 
	ON_WM_LBUTTONDOWN() 
	ON_WM_MOUSEMOVE() 
	ON_WM_RBUTTONDOWN() 
	ON_COMMAND(ID_PICK, OnPick) 
	ON_UPDATE_COMMAND_UI(ID_PICK, OnUpdatePick) 
	ON_COMMAND(ID_REDRAW, OnRedraw) 
	ON_WM_KEYDOWN() 
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen) 
	ON_COMMAND(ID_FILE_SAVE, OnFileSave) 
	ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) 
	//}}AFX_MSG_MAP 
	// Standard printing commands 
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) 
 
	ON_COMMAND_RANGE(ID_CREATE_LINE,  
					ID_CREATE_ARC, OnCreateEntity) 
	ON_UPDATE_COMMAND_UI_RANGE(ID_CREATE_LINE,  
					ID_CREATE_ARC, OnUpdateCreateCommand) 
	ON_COMMAND_RANGE(ID_MODIFY_MOVE,  
					ID_MODIFY_ERASE, OnModifyEntity) 
	ON_UPDATE_COMMAND_UI_RANGE(ID_MODIFY_MOVE,  
					ID_MODIFY_ERASE, OnUpdateModifyCommand) 
	//视图变换命令 
	ON_COMMAND_RANGE(ID_VIEW_REGION,ID_VIEW_PAN, OnViewCommand)// 
 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadView construction/destruction 
 
CVCadView::CVCadView() 
{ 
	// TODO: add construction code here 
	g_pView = this; 
	m_pCmd = NULL; 
	// 初始化世界坐标与屏幕坐标的关系 
	m_dOrgX = m_dOrgY = 0.; 
	scale = 1.; 
	m_bIsPrinting = FALSE; 
} 
 
CVCadView::~CVCadView() 
{ 
	if( m_pCmd ) 
		delete m_pCmd ; 
} 
 
BOOL CVCadView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadView drawing 
 
void CVCadView::OnDraw(CDC* pDC) 
{ 
	g_nRefresh ++; // 每次视窗被重新绘制时,刷新次数加 1 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	DrawCoord(pDC) ; 
	// TODO: add draw code for native data here 
	pDoc->Draw(pDC); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadView diagnostics 
 
#ifdef _DEBUG 
void CVCadView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CVCadView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CVCadDoc* CVCadView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVCadDoc))); 
	return (CVCadDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CVCadView message handlers 
 
void CVCadView::OnCreateEntity(int m_nID) 
{ 
	// 如果当前状态存在命令,那么 
	// 1. 取消该命令的操作 
	// 2. 删除该命令对象 
	// 3. 将命令指针设为空 
	if( m_pCmd ){  
		m_pCmd->Cancel(); 
		delete m_pCmd ; 
		m_pCmd = NULL;  
	} 
	// 下面根据不同的菜单命令创建不同的命令对象 
	switch(m_nID) 
	{ 
		case ID_CREATE_LINE: // 直线 
		{ 
			m_pCmd = new CCreateLine(); 
			break; 
		} 
		case ID_CREATE_RECTANGLE: // 矩形 
		{ 
			m_pCmd = new CCreateRect(); 
			break; 
		} 
		case ID_CREATE_CIRCLE: // 圆 
		{ 
			m_pCmd = new CCreateCircle(); 
			break; 
		} 
		case ID_CREATE_ARC: // 圆弧 
		{ 
			m_pCmd = new CCreateArc(); 
			break; 
		} 
	} 
} 
 
void CVCadView::OnUpdateCreateCommand(CCmdUI* pCmdUI) 
{ 
	int flag = 0 ; 
	switch(pCmdUI->m_nID) 
	{ 
		case ID_CREATE_LINE: 
		{ 
			if( (m_pCmd != NULL && m_pCmd->GetType() == ctCreateLine) ) 
				flag = 1; 
			break; 
		} 
		case ID_CREATE_RECTANGLE: 
		{ 
			if( (m_pCmd != NULL && m_pCmd->GetType() == ctCreateRectangle) ) 
				flag = 1; 
			break; 
		} 
		case ID_CREATE_CIRCLE: 
		{ 
			if( (m_pCmd != NULL && m_pCmd->GetType() == ctCreateCircle) ) 
				flag = 1; 
			break; 
		} 
		case ID_CREATE_ARC: 
		{ 
			if( (m_pCmd != NULL && m_pCmd->GetType() == ctCreateArc) ) 
				flag = 1; 
			break; 
		} 
		default: 
			break; 
	} 
	pCmdUI->SetCheck(flag); 
} 
 
void CVCadView::OnModifyEntity(int m_nID) 
{ 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT(pDoc) ; 
 
	// 如果当前状态存在命令,那么 
	// 1. 取消该命令的操作 
	// 2. 删除该命令对象 
	// 3. 将命令指针设为空 
	if( m_pCmd ){  
		m_pCmd->Cancel(); 
		delete m_pCmd ; 
		m_pCmd = NULL;  
	} 
 
	// 判断是否有实体图元被选中 
	if(pDoc->m_selectArray.GetSize() == 0) 
	{ 
		CString	strError = _T("请首先选取图元");	 
		AfxMessageBox(strError); 
		return; 
	} 
	// 下面根据不同的菜单命令创建不同的命令对象 
	switch(m_nID) 
	{ 
		case ID_MODIFY_MOVE:  
		{// 平移 
			m_pCmd = new CMove(); 
			break; 
		} 
		case ID_MODIFY_ROTATE:  
		{// 旋转 
			m_pCmd = new CRotate(); 
			break; 
		} 
		case ID_MODIFY_MIRROR:  
		{// 镜像 
			m_pCmd = new CMirror(); 
			break; 
		} 
		default: 
			//删除 
			Erase() ; 
			break; 
	} 
} 
void CVCadView::OnUpdateModifyCommand(CCmdUI* pCmdUI) 
{ 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT(pDoc) ; 
 
	// 判断是否有实体图元被选中 
	if(pDoc->m_selectArray.GetSize() == 0) 
	{ 
		pCmdUI->Enable(FALSE);		 
		return; 
	} 
 
	int flag = 0 ; 
	switch(pCmdUI->m_nID) 
	{ 
		case ID_MODIFY_MOVE: 
		{ 
			if( (m_pCmd != NULL && m_pCmd->GetType() == ctMove) ) 
				flag = 1; 
			break; 
		} 
		case ID_MODIFY_ROTATE: 
		{ 
			if( (m_pCmd != NULL && m_pCmd->GetType() == ctRotate) ) 
				flag = 1; 
			break; 
		} 
		case ID_MODIFY_MIRROR: 
		{ 
			if( (m_pCmd != NULL && m_pCmd->GetType() == ctMirror) ) 
				flag = 1; 
			break; 
		} 
		default: 
			break; 
	} 
	pCmdUI->SetCheck(flag); 
} 
 
void CVCadView::WorldtoScreen(const Position& pos, CPoint& screenPt) 
{ 
	// 获取当前客户区的大小 
	CRect rect ; 
	GetClientRect(&rect) ; 
	// 将屏幕原点设置为客户区的中心 
	int	nSOrgX = int((rect.left + rect.right) / 2 );///scale); 
	int nSOrgY = int((rect.top + rect.bottom) / 2 );///scale); 
	// 计算屏幕坐标值 
	screenPt.x = (int)((pos.x - m_dOrgX) / scale + nSOrgX) ; 
	screenPt.y = (int)(nSOrgY - (pos.y - m_dOrgY) / scale ) ; 
	CDC* pDC = GetDC(); 
	 
	if(m_bIsPrinting) 
		pDC->SetMapMode(MM_LOENGLISH);  
	else 
		pDC->SetMapMode(MM_TEXT);  
	pDC->LPtoDP(&screenPt); 
	ReleaseDC(pDC);	 
} 
 
void CVCadView::ScreentoWorld(const CPoint& pt, Position& pos) 
{ 
	CPoint screenPt = pt; 
	CDC* pDC = GetDC(); 
	pDC->SetMapMode(MM_TEXT); 
 
	pDC->DPtoLP(&screenPt); 
	ReleaseDC(pDC);	 
	// 获取当前客户区的大小 
	CRect rect ; 
	GetClientRect(&rect) ; 
	// 将屏幕原点设置为客户区的中心 
	int	nSOrgX = (rect.left + rect.right) / 2 ; 
	int nSOrgY = (rect.top + rect.bottom) / 2 ; 
	// 计算世界坐标值 
	pos.x = (screenPt.x - nSOrgX) * scale + m_dOrgX; 
	pos.y = (nSOrgY - screenPt.y ) * scale + m_dOrgY; 
} 
 
double CVCadView::GetScale() 
{ 
	return scale; 
} 
 
void CVCadView::SetScale(double dScale) 
{ 
	scale = dScale; 
} 
 
void CVCadView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	Position pos; 
	ScreentoWorld(point, pos); // 将设备坐标转换为世界坐标 
 
	if(m_pCmd) 
		m_pCmd->OnLButtonDown(nFlags, pos); 
	else 
		pDoc->OnLButtonDown(nFlags, pos); 
	 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void CVCadView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	Position pos; 
	ScreentoWorld(point, pos);// 将设备坐标转换为世界坐标 
 
	//获得状态条的指针 
	CStatusBar* pStatus=(CStatusBar*) 
		AfxGetApp()->m_pMainWnd->GetDescendantWindow(ID_VIEW_STATUS_BAR); 
	if(pStatus) 
	{ 
		char tbuf[40]; 
		sprintf(tbuf,"(%8.3f,%8.3f)",pos.x, pos.y); 
		//在状态条的第二个窗格中输出当前鼠标的位置 
		pStatus->SetPaneText(1,tbuf); 
	} 
	if(m_pCmd) 
		m_pCmd->OnMouseMove(nFlags, pos); 
	else 
		pDoc->OnMouseMove(nFlags, pos); 
 
	CView::OnMouseMove(nFlags, point); 
} 
 
void CVCadView::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	Position pos; 
	// 将设备坐标转换为世界坐标 
	ScreentoWorld(point, pos); 
 
	if(m_pCmd) 
		m_pCmd->OnRButtonDown(nFlags, pos); 
 
	CView::OnRButtonDown(nFlags, point); 
} 
 
void CVCadView::OnPick()  
{ 
	// TODO: Add your command handler code here 
	if(m_pCmd){ 
 
		delete m_pCmd; 
		m_pCmd = NULL; 
	} 
} 
 
void CVCadView::OnUpdatePick(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(m_pCmd == NULL ? 1 : 0) ; 
} 
///////////////////////////////////////////////////////////////////////////// 
// CVCadView printing 
 
BOOL CVCadView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// 将绘图板设置为2个标准页大小 
	pInfo->SetMaxPage(2); 
	return DoPreparePrinting(pInfo); 
} 
 
void CVCadView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) 
{ 
	// TODO: add extra initialization before printing 
	// 获得可打印区域(毫米值) 
	int nHorzSize = pDC->GetDeviceCaps(HORZSIZE); 
	int nVertSize = pDC->GetDeviceCaps(VERTSIZE); 
	// 计算页面的高度和宽度(逻辑单位)   
	m_nPageWidth = (int)((double)nHorzSize / 25.4 * 100.0); 
	m_nPageHeight = (int)((double)nVertSize / 25.4 * 100.0); 
} 
 
void CVCadView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
void CVCadView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)  
{ 
	pDC->SetMapMode(MM_TEXT);  
	if(pDC->IsPrinting()) 
	{ 
		pDC->SetMapMode(MM_LOENGLISH);  
		int nPages = pInfo->m_nCurPage - 1; 
		int x = (nPages & 1) * m_nPageWidth; 
		int y = (nPages / 2) * m_nPageHeight; 
		pDC->SetWindowOrg(x,y); 
	}	 
	CView::OnPrepareDC(pDC, pInfo); 
 
} 
void CVCadView::OnPrint(CDC* pDC, CPrintInfo* pInfo)  
{ 
	ASSERT_VALID(pDC); 
	pDC->SetWindowOrg(pInfo->m_rectDraw.left, 
		-pInfo->m_rectDraw.top); 
	 
	m_bIsPrinting=TRUE;	 
	// 打印页眉 
	PrintPageHeader(pDC,pInfo);  
	// 打印图形 
	CView::OnPrint(pDC, pInfo);  
	// 打印页脚 
	PrintPageFooter(pDC,pInfo); 
 
	m_bIsPrinting=FALSE; 
} 
 
 
void CVCadView::PrintPageHeader(CDC *pDC, CPrintInfo *pInfo) 
{ 
	// 获取设备描述表中缺省的字体 
	TEXTMETRIC tm; 
	pDC->GetTextMetrics(&tm); 
	// 创建新字体并将其选入设备描述表 
	CFont newFont; 
	newFont.CreateFont(-tm.tmHeight, 
		0,0,0, 
		FW_NORMAL, 
		FALSE, FALSE, 
		0, 
		ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 
		DEFAULT_QUALITY, DEFAULT_PITCH|FF_MODERN, 
		"Courier New"); 
	CFont* pOldFont = (CFont*)pDC->SelectObject(&newFont); 
 
	// 页眉中的文本右对齐 
	pDC->SetTextAlign(TA_RIGHT); 
	// 打印页眉文本 
	pDC->TextOut(pInfo->m_rectDraw.right, -25, "VCad 绘图系统"); 
 
	// 打印页眉中的水平直线 
	int y = - 35 - tm.tmHeight; 
	pDC->MoveTo(0,y); 
	pDC->LineTo(pInfo->m_rectDraw.right,y); 
 
	// 根据页眉占用的空间来调整可打印图形区域 
	y -= 25; 
	pInfo->m_rectDraw.top += y; 
 
	// 恢复以前的字体 
	pDC->SelectObject(pOldFont); 
} 
// 打印页脚 
void CVCadView::PrintPageFooter(CDC *pDC, CPrintInfo *pInfo) 
{ 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	 
	// 由文档保存的位置或者标题和当前的页码构成页脚的文本 
	// 如果文档没有被保存,则打印文档的标题名称;反之,则打印文档保存的位置 
	CString strFooter = pDoc->GetPathName(); 
	CString strTitle = pDoc->GetTitle(); 
	if(strTitle == "Untitled" || strTitle == "无标题") 
		strFooter = strTitle; 
	 
	// 文本左对齐 
	pDC->SetTextAlign(TA_LEFT); 
	// 打印文本 
	pDC->TextOut(pInfo->m_rectDraw.left, 
		pInfo->m_rectDraw.bottom + 100, strFooter); 
	 
	// 在页脚中添加页码信息 
	CString strPage; 
	strPage.Format("%s%d%s", "第", pInfo->m_nCurPage, "页"); 
	// 获取页码的宽度 
	CSize size = pDC->GetTextExtent(strFooter); 
	// 页码右对齐 
	pDC->TextOut(pInfo->m_rectDraw.right - size.cx, 
		pInfo->m_rectDraw.bottom + 100, strPage); 
 
	// 绘制页脚的水平上划线 
	TEXTMETRIC tm; 
	pDC->GetTextMetrics(&tm); 
	int y = pInfo->m_rectDraw.bottom + 90 + tm.tmHeight; 
	pDC->MoveTo(0, y); 
	pDC->LineTo(pInfo->m_rectDraw.right, y); 
} 
 
 
void CVCadView::OnRedraw()  
{ 
	// TODO: Add your command handler code here 
	g_pDoc ->UpdateAllViews(NULL) ; 
} 
// 
void CVCadView::OnViewCommand(int m_nID)  
{ 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT(pDoc) ; 
 
	CRect rc ; 
	GetClientRect(&rc) ; 
 
	if( m_pCmd ){ 
		delete m_pCmd ; 
		// 切记:在使用一个命令之前必须要清除上一个命令 
		m_pCmd = NULL;  
	} 
	switch(m_nID) 
	{ 
		case ID_VIEW_REGION: 
		{ 
			if( !(m_pCmd = new CZoomRgnCmd()) ) 
				AfxMessageBox("Failed!"); 
			pDoc->SetModifiedFlag(TRUE) ; 
			::Prompt("请输入移动的起始点:") ; 
			break; 
		} 
		case ID_VIEW_ZOOMIN: 
		{ 
			scale *= 0.618 ; 
			if(scale<1e-6) scale = 1. ; 
			pDoc->SetModifiedFlag(TRUE) ; 
			break; 
		} 
		case ID_VIEW_ZOOMOUT: 
		{ 
			scale/=0.618 ; 
			if(scale>1e+6) scale = 1. ; 
			pDoc->SetModifiedFlag(TRUE) ; 
			break; 
		} 
		case ID_VIEW_ZOOMALL: 
		{ 
			ZoomAll() ; 
			break; 
		} 
		case ID_VIEW_PAN: 
		{ 
			if(!(m_pCmd = new CViewPanCmd())) 
				AfxMessageBox("Failed!") ; 
			pDoc->SetModifiedFlag(TRUE) ; 
			break; 
		} 
		default: 
			break; 
	} 
	InvalidateRect(rc) ; 
} 
// 
void CVCadView::ZoomAll() 
{ 
	CVCadDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	CDC* pDC = GetDC() ; 
	//映射模式要一致 
	pDC->SetMapMode(MM_TEXT) ; 
 
	CRect rc ; 
	GetClientRect(&rc) ; 
	pDC->DPtoLP(&rc) ; 
	 
	double MinX, MaxX, MinY, MaxY ; 
	MinX = 1.e+6 ; 
	MinY = 1.e+6 ; 
	MaxX = - 1.e+6 ; 
	MaxY = - 1.e+6 ; 
 
	BOX2D pBox ; 
	POSITION pos; 
	pos = pDoc->m_EntityList.GetHeadPosition(); 
	// 如果链表中不存在任何图元,则不做任何操作直接返回 
	if(pos == NULL)   
		return ; 
	// 通过各图元的包围盒来计算出所有图元的包围盒 
	while(pos != NULL) 
	{ 
		CEntity* pEntity = (CEntity*)(pDoc->m_EntityList.GetNext(pos)) ; 
		pEntity->GetBox(&pBox) ; 
		if(MinX>pBox.min[0]) MinX = pBox.min[0] ; 
		if(MinY>pBox.min[1]) MinY = pBox.min[1] ; 
		if(MaxXscaley) 
		scale = scalex ; 
	else 
		scale = scaley ; 
 
	if(fabs(scale)<1e-6||fabs(scale)>1e+6) 
		scale = 1. ; 
	InvalidateRect(rc) ; 
} 
 
void CVCadView::DrawCoord(CDC *pDC) 
{ 
	CVCadDoc * pDoc = GetDocument() ; 
	ASSERT_VALID(pDoc) ; 
 
	CPoint sOrgp, sXp, sYp; 
	Position dOrgPnt(0,0) ; 
 
	WorldtoScreen(dOrgPnt,sOrgp) ; 
	pDC->TextOut(sOrgp.x-20,sOrgp.y-2,"O") ; 
 
	Position dtemppx(50,0) ; 
	WorldtoScreen(dtemppx,sXp) ; 
	pDC->TextOut(sXp.x+2,sXp.y-2,"X") ; 
 
	Position dtemppy(0,50) ; 
	WorldtoScreen(dtemppy,sYp) ; 
	pDC->TextOut(sYp.x-20,sYp.y-20,"Y") ; 
 
	pDC->MoveTo(sOrgp) ; 
	pDC->LineTo(sXp) ; 
	pDC->MoveTo(sOrgp) ; 
	pDC->LineTo(sYp) ; 
} 
 
void CVCadView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	// TODO: Add your message handler code here and/or call default 
	switch(nChar) 
	{ 
	case VK_NEXT: 
		scale *= 0.618 ; 
		if(scale<1e-6) scale = 1. ; 
		g_pDoc->SetModifiedFlag(TRUE) ; 
		break; 
	case VK_PRIOR: 
		scale /= 0.618 ; 
		if(scale>1e+6) scale = 1. ; 
		g_pDoc->SetModifiedFlag(TRUE) ; 
		break; 
	default:; 
	} 
	Invalidate(TRUE) ; 
 
	CView::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
//永久删除功能 
void CVCadView::Erase() 
{ 
	//获得文档类的指针 
	CVCadDoc * pDoc = GetDocument() ; 
	ASSERT_VALID(pDoc) ; 
	 
	CEntity* pSelEntity = NULL ; 
	POSITION pos = NULL ; 
	//在链表中查找被添加到选择集中图元 
	//并将其从链表中永远删除 
	for( int i = 0 ; i < pDoc->m_selectArray.GetSize() ; i++ ) 
	{ 
		pSelEntity = (CEntity*)pDoc->m_selectArray[i] ; 
		pos = pDoc->m_EntityList.Find(pSelEntity) ; 
		pDoc->m_EntityList.RemoveAt(pos) ; 
		delete pSelEntity ; 
		pSelEntity = NULL ; 
	} 
	//清空选择集 
	pDoc->m_selectArray.RemoveAll() ; 
	//更新文档,重新绘制 
	pDoc->UpdateAllViews(NULL) ; 
} 
 
//	打开文件	 
void CVCadView::OnFileOpen()  
{ 
	// TODO: Add your command handler code here 
	CVCadDoc* pDocument = GetDocument(); 
 
	BOOL	ret = FALSE; 
 
	//	如果当前文件为保存则先保存 
	int	status = 0; 
	ret = pDocument->IsModified(); 
	if(ret == TRUE)  
	{ 
	    status = AfxMessageBox(" 文件已修改,是否保存文件?",MB_YESNOCANCEL); 
	    if(status == IDCANCEL)  
		{ 
			return; 
	    } 
	    if(status == IDYES)  
		{ 
			AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND,ID_FILE_SAVE); 
	    } 
	} 
 
	extern BOOL GetCADName(BOOL bIsOpen,CString& sFileName);	//	得到CAD文件名 
	CString sFileName; 
    if (GetCADName(TRUE,sFileName)) 
	{ 
		pDocument->DeleteContents(); 
		pDocument->SetModifiedFlag(); 
 
		CFileException fe; 
		CFile* pFile = pDocument->GetFile(sFileName, 
			CFile::modeRead|CFile::shareDenyWrite, &fe); 
		if (pFile == NULL) 
		{ 
			pDocument->ReportSaveLoadException(sFileName, &fe, 
				FALSE, AFX_IDP_FAILED_TO_OPEN_DOC); 
		} 
 
		CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete); 
		loadArchive.m_pDocument = pDocument; 
		loadArchive.m_bForceFlat = TRUE; 
 
		//	读取文件 
		if (pFile->GetLength() != 0) 
		{ 
			GetDocument()->BeginWaitCursor(); 
			pDocument->Serialize(loadArchive); 
			GetDocument()->EndWaitCursor(); 
		} 
 
		pDocument->SetTitle(sFileName);	//	设置窗口标题 
		AfxGetApp()->AddToRecentFileList(sFileName);	//	添加最新文件列表 
 
		loadArchive.Close(); 
		pDocument->ReleaseFile(pFile, FALSE); 
 
		pDocument->SetModifiedFlag(FALSE); 
 
		Invalidate();	//	刷新绘图区 
	} 
} 
 
//	保存文件 
void CVCadView::OnFileSave()  
{ 
	// TODO: Add your command handler code here 
	CVCadDoc* pDoc = GetDocument(); 
	CFileException fe; 
	 
	//	如果文件未命名,则调“另存为”函数	 
	CString sFileName=pDoc->GetTitle(); 
	sFileName.MakeLower(); 
	if(sFileName=="untitled" || sFileName == "无标题") 
	{ 
		OnFileSaveAs(); 
		return; 
	} 
 
	//	创建文件 
	CFile* pFile = new CFile(sFileName, CFile::modeCreate | 
		CFile::modeWrite | CFile::shareExclusive);//, &fe); 
 
	if (pFile == NULL) 
		return; 
 
	CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete); 
	saveArchive.m_pDocument = pDoc; 
	saveArchive.m_bForceFlat = TRUE; 
 
	//	保存文件 
	pDoc->Serialize(saveArchive);	 
 
	//设置文档更新标记 
	pDoc->SetModifiedFlag(FALSE); 
 
	saveArchive.Close(); 
	pDoc->ReleaseFile(pFile, FALSE); 
 
} 
 
//	另存文件 
void CVCadView::OnFileSaveAs()  
{ 
	CVCadDoc* pDoc = GetDocument(); 
 
	// TODO: Add your command handler code here 
	extern BOOL GetCADName(BOOL bIsOpen,CString& sFileName);	//	得到CAD文件名 
	CString sFileName; 
    if (GetCADName(FALSE,sFileName)) 
	{ 
 
		CFileException fe; 
		CFile* pFile = new CFile(sFileName, CFile::modeCreate | 
			CFile::modeWrite | CFile::shareExclusive);//, &fe); 
 
		if (pFile == NULL) 
			return; 
 
		CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete); 
		saveArchive.m_pDocument = pDoc; 
		saveArchive.m_bForceFlat = TRUE; 
		TRY 
		{ 
			pDoc->Serialize(saveArchive);     
 
			pDoc->SetTitle(sFileName); 
			AfxGetApp()->AddToRecentFileList(sFileName); 
 
			saveArchive.Close(); 
			pDoc->ReleaseFile(pFile, FALSE); 
		} 
		CATCH_ALL(e) 
		{ 
			pDoc->ReleaseFile(pFile, TRUE); 
 
			TRY 
			{ 
				pDoc->ReportSaveLoadException(sFileName, e, 
					TRUE, AFX_IDP_FAILED_TO_SAVE_DOC); 
			} 
			END_TRY 
			e->Delete(); 
			return; 
		} 
		END_CATCH_ALL 
 
		pDoc->SetModifiedFlag(FALSE);     
 
    } 
 
}