www.pudn.com > 1012.zip > SCADView.cpp


// SCADView.cpp : implementation of the CSCADView class 
// 
 
#include "stdafx.h" 
#include "SCAD.h" 
 
#include "SCADDoc.h" 
#include "SCADView.h" 
#include "config.h" 
#include  
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CSCADView 
 
IMPLEMENT_DYNCREATE(CSCADView, CView) 
 
BEGIN_MESSAGE_MAP(CSCADView, CView) 
//{{AFX_MSG_MAP(CSCADView) 
ON_WM_CREATE() 
ON_WM_ERASEBKGND() 
ON_WM_SIZE() 
ON_WM_LBUTTONDOWN() 
ON_WM_LBUTTONUP() 
ON_WM_MOVE() 
ON_WM_MOUSEMOVE() 
ON_COMMAND(IDD_VIEW_PAN, OnViewPan) 
ON_COMMAND(IDD_VIEW_ZOOM, OnViewZoom) 
ON_WM_MOUSEWHEEL() 
ON_WM_RBUTTONDOWN() 
ON_COMMAND(IDD_VIEW_ZOOMRECT, OnViewZoomrect) 
ON_COMMAND(IDD_DRAW_LINE, OnDrawLine) 
	ON_COMMAND(ID_FILE_SAVE, OnFileSave) 
	ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) 
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen) 
	ON_COMMAND(IDD_DRAW_CIRCLE, OnDrawCircle) 
	ON_COMMAND(IDD_DRAW_RECTANGLE, OnDrawRectangle) 
	//}}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) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CSCADView construction/destruction 
 
CSCADView::CSCADView() 
{ 
	xOrg = -1000; 
	yOrg = -1000; 
	zOrg = -500; 
	xMax = 1000; 
	yMax = 1000; 
	zMax = 500; 
	 
	m_ptStart.Set(0.0,0.0,0.0); 
	m_ptEnd.Set(0.0,0.0,0.0); 
	m_eActionMode = NONE; 
	m_eNodeType = new BYTE; 
	*m_eNodeType = BASENODE; 
	m_bLButtonDown = false; 
	 
	m_iOpStep = 0; 
	nIndex=0;//当前没有绘制图元 
	bFileSaved=FALSE;//没有保存过文件 
	 
} 
 
CSCADView::~CSCADView() 
{ 
} 
 
BOOL CSCADView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
    cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; 
	 
	 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CSCADView drawing 
 
void CSCADView::OnDraw(CDC* pDC) 
{ 
	CSCADDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	 
	HDC hdc; 
	HGLRC rc; 
	 
	CSCADView::GetCurrent(hdc, rc);//Store current rendering and device contexts 
	MakeActive();//Make view's rendering context current 
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
	glPushMatrix(); 
	//RenderScene(); 
	////////////////////////////////////////////////////////////////////////// 
	POSITION pos=pDoc->RecordList.GetHeadPosition(); 
	while(pos!=NULL) 
	{ 
		BYTE *NodeType; 
		NodeType=(BYTE*)pDoc->RecordList.GetNext(pos); 
		switch(*NodeType) 
		{ 
		case LINENODE: 
			CLineNode *pline; 
			pline=(CLineNode *)pDoc->RecordList.GetNext(pos); 
			pline->Draw(); 
			break; 
		case RECTANGLENODE: 
			CRectangleNode *pRec; 
			pRec = (CRectangleNode *)pDoc->RecordList.GetNext(pos); 
			pRec->Draw(); 
			break; 
		case CIRCLENODE: 
			CCircleNode *pCircle; 
			pCircle = (CCircleNode *)pDoc->RecordList.GetNext(pos); 
			pCircle->Draw(); 
			break; 
		}		 
	} 
	////////////////////////////////////////////////////////////////////////// 
 
	glPopMatrix(); 
	// Tell OpenGL to flush its pipeline 
	glFinish(); 
	 
	// Now Swap the buffers 
	if ( FALSE == SwapBuffers(m_pDC->GetSafeHdc())) 
		return; 
	//SetLimits(); 
	 
	CSCADView::SetCurrent(hdc, rc);//Restore last rendering and device contexts 
	CView::OnDraw(pDC); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CSCADView printing 
 
BOOL CSCADView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CSCADView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CSCADView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CSCADView diagnostics 
 
#ifdef _DEBUG 
void CSCADView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CSCADView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CSCADDoc* CSCADView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSCADDoc))); 
	return (CSCADDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CSCADView message handlers 
 
int CSCADView::SetupPixelFormat() 
{ 
	static PIXELFORMATDESCRIPTOR pfd =  
	{ 
        sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd 
			1,                              // version number 
			PFD_DRAW_TO_WINDOW |            // support window 
			PFD_SUPPORT_OPENGL |			// support OpenGL           
			PFD_DOUBLEBUFFER,				// double buffered 
			PFD_TYPE_RGBA,                  // RGBA type 
			24,                             // 24-bit color depth 
			0, 0, 0, 0, 0, 0,               // color bits ignored 
			0,                              // no alpha buffer 
			0,                              // shift bit ignored 
			0,                              // no accumulation buffer 
			0, 0, 0, 0,                     // accum bits ignored 
			32,                             // 32-bit z-buffer 
			0,                              // no stencil buffer 
			0,                              // no auxiliary buffer 
			PFD_MAIN_PLANE,                 // main layer 
			0,                              // reserved 
			0, 0, 0                         // layer masks ignored 
    }; 
	int m_PixelFormat; 
     
    if ( 0 == (m_PixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) ) 
        return FALSE; 
	 
    if ( FALSE == ::SetPixelFormat(m_pDC->GetSafeHdc(), m_PixelFormat, &pfd) ) 
        return FALSE; 
	 
    return TRUE; 
} 
 
int CSCADView::InitializeOpenGL() 
{ 
    m_pDC = new CClientDC(this); 
	 
    if ( NULL == m_pDC ) // failure to get DC 
		return FALSE; 
	 
	if (!SetupPixelFormat()) 
	{ 
        return FALSE; 
	} 
	 
	//	For Color-Index mode, you'd probably create your palette here, right 
	//	after you select the pixel format 
	 
    if ( 0 == (m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc() ) ) ) 
		return FALSE; 
	 
    if ( FALSE == MakeActive()) 
		return FALSE; 
	 
	// specify black as clear color 
    ::glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
	// specify the back of the buffer as clear depth 
    ::glClearDepth(1.0f); 
	// enable depth testing 
    ::glEnable(GL_DEPTH_TEST); 
	 
	return TRUE; 
} 
 
BOOL CSCADView::MakeActive() 
{ 
	return SetCurrent(m_pDC->GetSafeHdc(), m_hRC); 
	 
} 
 
BOOL CSCADView::SetCurrent(HDC hdc, HGLRC rc) 
{ 
	if (FALSE == ::wglMakeCurrent(hdc, rc)) 
		return FALSE; 
	return TRUE; 
} 
 
void CSCADView::GetCurrent(HDC &hdc, HGLRC &rc) 
{ 
	hdc = ::wglGetCurrentDC(); 
	rc =  ::wglGetCurrentContext();  
} 
 
void CSCADView::RenderScene() 
{ 
	glColor3d(0.0, 0.0, 1.0); 
	 
	glBegin(GL_LINE_LOOP); 
	{ 
		glVertex3d(-500.0,-500.0,0.0); 
		glVertex3d(-500.0,500.0,0.0); 
		glVertex3d(500.0,500.0,	0.0); 
		glVertex3d(500.0,-500.0,0.0); 
		 
	} 
	glEnd(); 
	 
	CPoint3d ptStart,ptEnd; 
	ptStart.Set(-500.0,-500.0,0.0); 
	ptEnd.Set(500.0,500.0,	0.0); 
	//DrawRectangle(ptStart,ptEnd); 
	 
	auxWireSphere(300.0); 
	return; 
 
} 
 
 
 
int CSCADView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	GetParentFrame()->ModifyStyle(FWS_ADDTOTITLE,0); 
	 
	InitializeOpenGL(); 
	return 0; 
} 
 
BOOL CSCADView::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	return TRUE; 
} 
 
void CSCADView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	SetupOrtho(cx, cy);	// TODO: Add your message handler code here 
	CSCADDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	pDoc->m_pScenceNode->SaveRange(xOrg,xMax,yOrg,yMax,zOrg,zMax); 
} 
 
void CSCADView::SetupOrtho(int cx, int cy) 
{ 
	if ( 0 >= cx || 0 >= cy ) 
		return; 
	 
	 
	GLdouble dAspect = (double) (yMax-yOrg) /(xMax-xOrg) ;  
	 
	glViewport(0,0,cx,cy);	 
	// select the viewing volumn 
    ::glMatrixMode ( GL_PROJECTION ); 
    ::glLoadIdentity (); 
	 
	GLdouble dx = xMax - xOrg; 
	GLdouble dy = yMax - yOrg;	 
	 
	if(fabs(dx) > 0.001 || fabs(dy) > 0.001) 
	{		 
		if(dx > dy) 
		{ 
			 
			GLdouble dAspect = (double) cy / cx; 
			yMax = yOrg + dx*dAspect; 
			::glOrtho( xOrg, xMax, yOrg, yMax, -zMax, zMax); 
		} 
		else 
		{ 
			GLdouble dAspect = (double)cx / cy ; 
			xMax = yOrg + dy *dAspect; 
			::glOrtho( xOrg, xMax, yOrg, yMax, -zMax, zMax); 
		} 
		gluLookAt(0.0,0.0,0.5*zMax,0.0,0.0,0.0,0.0,1.0,0.0); 
	} 
	// switch back to the modelview matrix and clear it 
	::glMatrixMode( GL_MODELVIEW ); 
	::glLoadIdentity(); 
} 
 
void CSCADView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	CSCADDoc* pDoc=GetDocument(); 
	m_bLButtonDown = true; 
	ConvertToWCS(point,m_ptLButtonDown); 
	if (m_eActionMode == ZOOMRECT) 
	{ 
		if (m_iOpStep ==0) //如果一操作没有完成 
		{ 
			ConvertToWCS(point,m_ptStart);//将当前点赋值给起点和终点 
			ConvertToWCS(point,m_ptEnd); 
			DrawRectangle(m_ptStart,m_ptEnd);//绘制矩形 
			m_iOpStep = 1;			 
		} 
		else 
		{//第一步操作完成即第一点已经选取 
			//完成区域缩放 
			m_iOpStep = 0; 
			DrawRectangle(m_ptStart,m_ptEnd); 
			 
			ConvertToWCS(point,m_ptEnd); 
			xOrg = min(m_ptStart.x, m_ptEnd.x); 
			xMax = max(m_ptStart.x, m_ptEnd.x); 
			yOrg = min(m_ptStart.y, m_ptEnd.y); 
			yMax = max(m_ptStart.y, m_ptEnd.y); 
			 
			SetupOrtho(); 
			Invalidate(); 
			 
		} 
	} 
	else if (m_eActionMode == DRAW) 
	{ 
		switch(*m_eNodeType) 
		{ 
		case LINENODE: 
			if (m_iOpStep ==0) //如果第一步操作没有完成 
			{ 
				ConvertToWCS(point,m_ptStart);//将当前点赋值给起点和终点 
				ConvertToWCS(point,m_ptEnd); 
				DrawLine(m_ptStart,m_ptEnd);// 
				m_iOpStep = 1; 
			} 
			else 
			{ 
				//第一步操作完成即第一点已经选取,完成向场景中添加节点 
				m_iOpStep = 0;	 
				DrawLine(m_ptStart,m_ptEnd); 
 
				m_pLineNode = new CLineNode; 
				m_pLineNode->m_ptStart=m_ptStart; 
				m_pLineNode->m_ptEnd=m_ptEnd; 
				nIndex+=1; 
				m_pLineNode->nIndex = nIndex; 
				m_pLineNode->SetName("line01"); 
				pDoc->RecordList.AddTail(m_eNodeType); 
				pDoc->RecordList.AddTail(m_pLineNode); 
				m_pLineNode = NULL; 
			}			 
			break; 
		case CIRCLENODE: 
			if (m_iOpStep ==0) //如果第一步操作没有完成 
			{ 
				ConvertToWCS(point,m_ptStart);//将当前点赋值给起点和终点 
				ConvertToWCS(point,m_ptEnd); 
				DrawLine(m_ptStart,m_ptEnd); 
				DrawCircle(m_ptStart,m_ptEnd); 
				m_iOpStep = 1; 
			} 
			else 
			{ 
				//第一步操作完成即第一点已经选取,完成向场景中添加节点 
				m_iOpStep = 0;	 
				DrawLine(m_ptStart,m_ptEnd); 
				DrawCircle(m_ptStart,m_ptEnd); 
				double radius = m_ptStart.DistanceTo(m_ptEnd); 
 
				m_pCircleNode = new CCircleNode; 
				m_pCircleNode->SetCenter(m_ptStart); 
				m_pCircleNode->SetRadius(radius) ; 
				nIndex+=1; 
				m_pCircleNode->nIndex = nIndex; 
				m_pCircleNode->SetName("circle01"); 
				pDoc->RecordList.AddTail(m_eNodeType); 
				pDoc->RecordList.AddTail(m_pCircleNode); 
				m_pCircleNode = NULL; 
			}			 
			break;	 
		case RECTANGLENODE: 
			if (m_iOpStep ==0) //如果一操作没有完成 
			{ 
				ConvertToWCS(point,m_ptStart);//将当前点赋值给起点和终点 
				ConvertToWCS(point,m_ptEnd); 
				DrawRectangle(m_ptStart,m_ptEnd);//绘制矩形 
				m_iOpStep = 1;			 
			} 
			else 
			{//第一步操作完成即第一点已经选取 
				//完成区域缩放 
				m_iOpStep = 0; 
				DrawRectangle(m_ptStart,m_ptEnd); 
				m_pRectangleNode = new CRectangleNode; 
				m_pRectangleNode->m_ptStart=m_ptStart; 
				m_pRectangleNode->m_ptEnd=m_ptEnd; 
				nIndex+=1; 
				m_pRectangleNode->nIndex = nIndex; 
				m_pRectangleNode->SetName("rectangle01"); 
				pDoc->RecordList.AddTail(m_eNodeType); 
				pDoc->RecordList.AddTail(m_pRectangleNode); 
				m_pLineNode = NULL; 
			} 
			break; 
		default: 
			break; 
		} 
 
	} 
	Invalidate(); 
				 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void CSCADView::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	m_bLButtonDown = false; 
	m_ptCurrent = point; 
	 
	CView::OnLButtonUp(nFlags, point); 
} 
 
void CSCADView::ConvertToWCS(CPoint &inPoint, CPoint3d &outPt) 
{ 
	GLdouble modelMatrix[16]; 
	GLdouble projMatrix[16]; 
	GLint viewport[4]; 
	//GLdouble objx, objy, objz; 
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); 
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); 
	glGetIntegerv(GL_VIEWPORT, viewport); 
	CRect rect; 
	GetClientRect(&rect); 
	int y = rect.Height() - inPoint.y; 
	gluUnProject(inPoint.x, y, 0,  
		modelMatrix, projMatrix, viewport,  
		&outPt.x, &outPt.y, &outPt.z);  
} 
 
void CSCADView::DrawRectangle(CPoint3d ptStart, CPoint3d ptEnd) 
{ 
	glDrawBuffer(GL_FRONT); 
	GLboolean depthtest = ::glIsEnabled(GL_DEPTH_TEST); 
	glDisable(GL_DEPTH_TEST); 
	GLenum depthfunc, logicop; 
	glGetIntegerv(GL_DEPTH_FUNC,(GLint*) &depthfunc); 
	glDepthFunc(GL_LEQUAL); 
	 
	glEnable(GL_COLOR_LOGIC_OP); 
	glGetIntegerv(GL_LOGIC_OP_MODE,(GLint*) &logicop); 
	glLogicOp(GL_XOR); 
	 
	glColor3d(1.0,1.0,1.0); 
	glBegin(GL_LINE_LOOP); 
	glVertex2f(ptStart.x, ptStart.y); 
	glVertex2f(ptEnd.x, ptStart.y); 
	glVertex2f(ptEnd.x, ptEnd.y); 
	glVertex2f(ptStart.x, ptEnd.y); 
	glEnd(); 
 
	glDrawBuffer(GL_BACK); 
	if(depthtest) 
		glEnable(GL_DEPTH_TEST); 
	 
	glDepthFunc(depthfunc); 
	glLogicOp(logicop); 
} 
 
void CSCADView::OnMove(int x, int y)  
{ 
	CView::OnMove(x, y); 
	 
} 
 
void CSCADView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	CView::OnMouseMove(nFlags, point); 
	m_ptCurrent =  point; 
	//获取工作区域 
	CRect rect; 
	GetClientRect(rect); 
	if (rect.PtInRect(point))  
	{ 
		 
		if (m_eActionMode == PAN)  
		{	 
			if (m_bLButtonDown)  
			{ 
				//完成场景平移操作 
				CPoint3d pt_End; 
				ConvertToWCS(point,pt_End); 
				 
				GLdouble distX = pt_End.x - m_ptLButtonDown.x; 
				GLdouble distY = pt_End.y - m_ptLButtonDown.y; 
				 
				xOrg -= distX; 
				xMax -= distX; 
				yOrg -= distY; 
				yMax -= distY; 
				 
				SetupOrtho(); 
				Invalidate(); 
			} 
			////return; 
		} 
		else if (m_eActionMode ==ZOOM) 
		{ 
			if (m_bLButtonDown)  
			{ 
				//完成场景缩放操作 
				CPoint3d pt_End; 
				ConvertToWCS(point,pt_End); 
				 
				GLdouble distY = pt_End.y - m_ptLButtonDown.y; 
				if (yMax <= 0.000001)  
				{ 
					yMax = 1.0; 
				} 
				xOrg = xOrg + distY*(xMax/yMax)*0.05; 
				xMax = xMax - distY*(xMax/yMax)*0.05; 
				yOrg = yOrg + distY*0.05; 
				yMax = yMax - distY*0.05; 
				SetupOrtho(); 
				Invalidate(); 
			} 
			//return; 
		} 
		else if (m_eActionMode ==ZOOMRECT)  
		{ 
			////////////////////////////////////////////////////////////////////////// 
			///****局部放大时候对应的移动状态下的处理情况,和鼠标是否落下无关***/// 
			//****绘制临时矩形*****// 
			if (m_iOpStep == 1)  
				DrawRectangle(m_ptStart,m_ptEnd); 
			 
			ConvertToWCS(point,m_ptEnd); 
			 
			if (m_iOpStep == 1)  
				DrawRectangle(m_ptStart,m_ptEnd); 
		} 
		else if (m_eActionMode ==DRAW)  
		{ 
			//移动时候绘制直线的轨迹 
			switch(*m_eNodeType)  
			{ 
			case LINENODE: 
				if (m_iOpStep == 1)  
					DrawLine(m_ptStart,m_ptEnd); 
				ConvertToWCS(point,m_ptEnd); 
				if (m_iOpStep == 1)  
					DrawLine(m_ptStart,m_ptEnd); 
				break; 
			case CIRCLENODE: 
				if (m_iOpStep == 1) { 
					DrawLine(m_ptStart,m_ptEnd); 
					DrawCircle(m_ptStart,m_ptEnd); 
				} 
				ConvertToWCS(point,m_ptEnd); 
				if (m_iOpStep == 1){  
					DrawLine(m_ptStart,m_ptEnd); 
					DrawCircle(m_ptStart,m_ptEnd); 
				} 
				//CDC* pDC; 
				//pDC = GetDC(); 
				//CString strPt; 
				//strPt.Format("%.2f,%.2f",m_ptEnd.x,m_ptEnd.y); 
				//DispCurPt(strPt,pDC,point); 
				break; 
			case  RECTANGLENODE: 
				if (m_iOpStep == 1)  
					DrawRectangle(m_ptStart,m_ptEnd); 
 
				ConvertToWCS(point,m_ptEnd); 
 
				if (m_iOpStep == 1)  
					DrawRectangle(m_ptStart,m_ptEnd); 
				break; 
			default: 
				break; 
			} 
			 
		} 
		 
	} 
} 
 
void CSCADView::SetupOrtho() 
{ 
	CRect rect; 
	GetClientRect(&rect); 
	SetupOrtho(rect.Width(), rect.Height()); 
	return; 
} 
 
void CSCADView::OnViewPan()  
{ 
	m_eActionMode =  PAN; 
	 
} 
 
void CSCADView::OnViewZoom()  
{ 
	m_eActionMode =  ZOOM;	 
} 
 
BOOL CSCADView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)  
{ 
	if (zDelta<0)  
	{ 
		GLdouble width = xMax - xOrg; 
		GLdouble height = yMax - yOrg; 
		xOrg = xOrg - width*0.1; 
		xMax = xMax + width*0.1; 
		yOrg = yOrg - height*0.1; 
		yMax = yMax + height*0.1; 
		SetupOrtho(); 
		Invalidate(); 
	} 
	else 
	{ 
		GLdouble width = xMax - xOrg; 
		GLdouble height = yMax - yOrg; 
		xOrg = xOrg + width*0.1; 
		xMax = xMax - width*0.1; 
		yOrg = yOrg + height*0.1; 
		yMax = yMax - height*0.1; 
		SetupOrtho(); 
		Invalidate();		 
	} 
	 
	return CView::OnMouseWheel(nFlags, zDelta, pt); 
} 
 
void CSCADView::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
	m_eActionMode = NONE; 
	CView::OnRButtonDown(nFlags, point); 
} 
 
void CSCADView::OnViewZoomrect()  
{ 
	m_eActionMode =ZOOMRECT; 
	m_iOpStep = 0; 
} 
 
void CSCADView::OnDrawLine()  
{ 
	m_eActionMode = DRAW; 
	m_iOpStep = 0; 
	*m_eNodeType = LINENODE; 
} 
 
void CSCADView::DrawLine(CPoint3d ptStart, CPoint3d ptEnd) 
{ 
	glDrawBuffer(GL_FRONT); 
	GLboolean depthtest = glIsEnabled(GL_DEPTH_TEST); 
	glDisable(GL_DEPTH_TEST); 
	GLenum depthfunc, logicop; 
	glGetIntegerv(GL_DEPTH_FUNC,(GLint*) &depthfunc); 
	glDepthFunc(GL_LEQUAL); 
	 
	glEnable(GL_COLOR_LOGIC_OP); 
	glGetIntegerv(GL_LOGIC_OP_MODE,(GLint*) &logicop); 
	glLogicOp(GL_XOR); 
	 
	glColor3d(1.0,1.0,1.0); 
	glBegin(GL_LINES); 
	glVertex2f(ptStart.x, ptStart.y); 
	glVertex2f(ptEnd.x, ptEnd.y); 
	glEnd(); 
	 
	glDrawBuffer(GL_BACK); 
	if(depthtest) 
		glEnable(GL_DEPTH_TEST); 
	glDepthFunc(depthfunc); 
	glLogicOp(logicop); 
} 
 
void CSCADView::OnFileSave()  
{ 
	if(bFileSaved) 
	{ 
		Save();	// 已经有文件名,修改图形文件 
	} 
	else 
		OnFileSaveAs();	 
	 
} 
 
void CSCADView::OnFileSaveAs()  
{ 
	CFileDialog	file(0, // 1-文件打开, 0-文件另存为 
		".scd|*.*", 
		NULL, 
		OFN_OVERWRITEPROMPT | OFN_NOREADONLYRETURN , 
		"绘图文件 (*.scd)|*.scd|All Files (*.*)|*.*||", 
		NULL); 
	if(file.DoModal()==IDOK) 
	{ 
		path = file.GetPathName(); 
		fileName = file.GetFileTitle(); 
		Save(); 
		////if(!AddIcon()) 
			//MessageBox("保存文件失败!","错误"); 
	}	 
} 
 
 
void CSCADView::Save()  
{ 
	CFile	save; 
////////////////////////////////////////// 
/*										// 
		modeRead =          0x0000,		// 
		modeWrite =         0x0001,		// 
		modeReadWrite =     0x0002,		// 
		modeCreate =        0x1000,		// 
*/										// 
////////////////////////////////////////// 
	save.Open(path,0x0001|0x1000,NULL); 
	CSCADDoc *pDoc=GetDocument(); 
	 
	POSITION pos=pDoc->RecordList.GetHeadPosition(); 
	while(pos!=NULL) 
	{ 
 		BYTE *style; 
		style=(BYTE*)pDoc->RecordList.GetNext(pos); 
		save.Write(style,sizeof(BYTE)); 
		switch(*style) 
		{ 
		case LINENODE: 
			save.Write((CLineNode*)pDoc->RecordList.GetAt(pos),sizeof(CLineNode)); 
			break; 
		case  RECTANGLENODE: 
			save.Write((CRectangleNode*)pDoc->RecordList.GetAt(pos),sizeof(CRectangleNode)); 
			break; 
		case  CIRCLENODE: 
			save.Write((CRectangleNode*)pDoc->RecordList.GetAt(pos),sizeof(CRectangleNode)); 
			break; 
		} 
	} 
	save.Close(); 
	pDoc->SetModifiedFlag(FALSE); 
	bFileSaved=TRUE; 
	GetParent()->SetWindowText(fileName);	 
} 
 
void CSCADView::OnFileOpen()  
{ 
	CSCADDoc *pDoc=GetDocument(); 
	 
	CFileDialog	file(1, // 1-文件打开, 0-文件另存为 
		".scd|*.*", 
		NULL, 
		OFN_OVERWRITEPROMPT , 
		"绘图文件 (*.scd)|*.scd|All Files (*.*)|*.*||", 
		NULL); 
	if(file.DoModal()==IDOK) 
	{ 
		 
		path = file.GetPathName(); 
		fileName=file.GetFileTitle(); 
		CFile	file; 
		if(!file.Open(path,0x0000,NULL)) return; 
		if(!pDoc->RecordList.IsEmpty())//如果文档数据内容非空则清空之 
			pDoc->RecordList.RemoveAll(); 
		 
		DWORD   CurFilePointer=file.GetPosition();//得到文件指针当前位置 
		DWORD   FileEndPointer=file.GetLength();//得到文件长度 
		 
		while(CurFilePointerRecordList.AddTail(style);//将图元类型加入链表 
			switch(*style) 
			{ 
				//如果图元是直线 
			case LINENODE: 
				CLineNode* line; 
				line=new CLineNode; 
				file.Read(line,sizeof(CLineNode)); 
				pDoc->RecordList.AddTail(line); 
				break; 
 
			case  RECTANGLENODE: 
				CRectangleNode *pRectangle; 
				pRectangle = new CRectangleNode; 
				file.Read(pRectangle,sizeof(CRectangleNode)); 
				pDoc->RecordList.AddTail(pRectangle); 
			case  CIRCLENODE: 
				CCircleNode* pCircle; 
				pCircle = new CCircleNode; 
				file.Read(pCircle,sizeof(CCircleNode)); 
				pDoc->RecordList.AddTail(pCircle); 
			default: 
				break; 
 
			} 
			CurFilePointer=file.GetPosition();//获得当前文件指针位置 
		} 
		file.Close();//关闭文件 
	} 
	 
	bFileSaved=TRUE; 
	pDoc->UpdateAllViews(NULL,0,NULL);//重绘窗口 
	GetParent()->SetWindowText(fileName); 
	 
} 
 
void CSCADView::DispCurPt(CString str, CDC *pDC, CPoint point) 
{ 
	//显示当前坐标 
	pDC->SetTextColor(RGB(255, 0, 0));		//设置字体颜色 
	pDC->SetBkMode(TRANSPARENT);		//设置为透明背景色 
	 
	//输出 
	CSize sizeCordWidth = pDC->GetOutputTextExtent(str); 
	int iOffsetX = 0, iOffsetY = 0; 
	//获取工作区域 
	CRect rect; 
	GetClientRect(rect); 
	//移到边界时,调整显示位置 
	if((rect.Width() - point.x) <= (sizeCordWidth.cx + 25)) 
		iOffsetX = -(sizeCordWidth.cx + 40); 
	if ((rect.Height() - point.y) <= (sizeCordWidth.cy + 25)) 
		iOffsetY = -(sizeCordWidth.cy + 40); 
	pDC->TextOut(point.x + 20 + iOffsetX, point.y + 20 + iOffsetY, str); 
	ReleaseDC(pDC); 
	 
} 
 
void CSCADView::DrawCircle(CPoint3d ptCen, double dLen,int iNum) 
{ 
	glDrawBuffer(GL_FRONT); 
	GLboolean depthtest = glIsEnabled(GL_DEPTH_TEST); 
	glDisable(GL_DEPTH_TEST); 
	GLenum depthfunc, logicop; 
	glGetIntegerv(GL_DEPTH_FUNC,(GLint*) &depthfunc); 
	glDepthFunc(GL_LEQUAL); 
	 
	glEnable(GL_COLOR_LOGIC_OP); 
	glGetIntegerv(GL_LOGIC_OP_MODE,(GLint*) &logicop); 
	glLogicOp(GL_XOR); 
	 
	glColor3d(1.0,1.0,1.0); 
	glPushMatrix(); 
	glTranslatef(ptCen.x,ptCen.y,0.0); 
	glBegin(GL_LINE_LOOP ); 
	double dStepAng = PI * 2.0 /iNum; 
	double x,y; 
	for(int i = 0; i<= iNum;i++) 
	{ 
		x= dLen* cos(i*dStepAng); 
		y = dLen*sin(i*dStepAng); 
		glVertex2f(x,y); 
	} 
	glEnd(); 
	glPopMatrix(); 
	 
	glDrawBuffer(GL_BACK); 
	if(depthtest) 
		glEnable(GL_DEPTH_TEST); 
	glDepthFunc(depthfunc); 
	glLogicOp(logicop); 
} 
 
void CSCADView::OnDrawCircle()  
{ 
	m_eActionMode = DRAW; 
	m_iOpStep = 0; 
	*m_eNodeType = CIRCLENODE;	 
} 
 
void CSCADView::DrawCircle(CPoint3d &ptS, CPoint3d &ptE) 
{ 
	//glTranslatef(ptS.x,ptS.y,0.0); 
	double dRadius = ptS.DistanceTo(ptE); 
	DrawCircle(ptS,dRadius,72); 
} 
 
void CSCADView::OnDrawRectangle()  
{ 
	m_eActionMode = DRAW; 
	m_iOpStep = 0; 
	*m_eNodeType = RECTANGLENODE;		 
}