⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drawview.cpp

📁 陈建春<用VC++开发GIS系统>源码.适合于GIS学习者,以及学习图形图象编程的朋友.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					m_pSelection = pItem;   // set selection to last inserted item
					VPtoDP(x1,y1,&pItem->m_X1,&pItem->m_Y1);
					VPtoDP(x2,y2,&pItem->m_X2,&pItem->m_Y2);
					pDoc->UpdateAllViews(NULL);
				}
				CATCH(CException, e)
				{
					if (pItem != NULL)
					{
						ASSERT_VALID(pItem);
						pItem->Delete();
					}
					AfxMessageBox(IDP_FAILED_TO_CREATE);
				}
				END_CATCH
				EndWaitCursor();
			}
			PushNumb=0;				//完成操作,左键按下数置0
			m_DrawCurrent=0;		//完成一次后,不继续运行此功能
			ReleaseCapture();		//释放捕捉的鼠标
		}
    }
	else if(m_DrawCurrent==30)		//进行鼠标选择图形操作
	{
		if(pDoc->n_GraphSelect==2000)	//如果选中的图形元素数是2000则不再选中
		{
			AfxMessageBox("最多只能选择2000个图形元素");
			return;
		}
		xx1=m_xStart+blc*point.x;               //点中点的实际x坐标
		yy1=m_yStart+blc*(m_hScreen-point.y);  //点中点的实际y坐标
		float jl=blc*4;            //点中范围(4个像素的实际距离)
		//以下对各种元素进行检查,计算是否点中(线,连续直线,圆和圆弧)
		
		BOOL pb=pDoc->PointSelect(xx1,yy1,jl,blc,&Lb,&Index,&pbh);
		if(pb)	//如果选中了图形元素,记录下选中顶图形元素,特殊显示此图形元素
		{  
			BOOL pb1=pDoc->AddSelectList(Lb,Index,pbh);
			if(pb1)
				pDoc->DrawGraph(&ht,Lb,Index,0,1,m_bColor);
		}	
		else
		{
			CDrawCntrItem* pItemHit=NULL;
			POSITION pos=pDoc->GetStartPosition();
			while(pos!=NULL)
			{
				CDrawCntrItem* pItem=(CDrawCntrItem*)pDoc->GetNextItem(pos);
				if(pItem->IsPoint(point))
					pItemHit=pItem;
			}
			if(pItemHit==NULL||m_pSelection!=pItemHit)
			{
				COleClientItem * pActiveItem=GetDocument()->GetInPlaceActiveItem(this);
				if(pActiveItem!=NULL&&pActiveItem!=pItemHit)
					pActiveItem->Close();
			}
			Invalidate();
			m_pSelection=pItemHit;
			if(pItemHit!=NULL)
			{
				pDoc->b_IsOleSelect=TRUE;
				pItemHit->b_Select=TRUE;
				CRectTracker tracker;
				PutTracker(pItemHit,&tracker);
				UpdateWindow();
				if(tracker.Track(this,point))
				{
					Invalidate();
					VPtoDP(tracker.m_rect.left,tracker.m_rect.bottom,&pItemHit->m_X1,&pItemHit->m_Y1);
					VPtoDP(tracker.m_rect.right,tracker.m_rect.top,&pItemHit->m_X2,&pItemHit->m_Y2);
					GetDocument()->SetModifiedFlag();
				}
			}
		}
	}
	else if(m_DrawCurrent==31)		//进行鼠标选择图形操作
	{
		CString m_str;
		char p1[9];
		xx1=m_xStart+blc*point.x;               //点中点的实际x坐标
		yy1=m_yStart+blc*(m_hScreen-point.y);  //点中点的实际y坐标
		float jl=blc*4;            //点中范围(4个像素的实际距离)
		BOOL pb=pDoc->PointSelect(xx1,yy1,jl,blc,&Lb,&Index,&pbh);
		if(pb)
		{
			if(m_pLinkSet->IsOpen())
				m_pLinkSet->Close();
			m_str="(graph_id=";
			sprintf(p1,"%d",Lb);
			m_str+=p1;
			m_str+=") AND (element_id=";
			sprintf(p1,"%d",pbh);
			m_str+=p1;
			m_str+=")";
			m_pLinkSet->m_strFilter=m_str;
			m_pLinkSet->Open();
			if(m_pLinkSet->IsBOF())
			{
				m_pLinkSet->Close();
				return;
			}
			CDataLinkDlg pDg1(pDoc,m_pLinkSet);
			pDg1.DoModal();
		}
	}
	else if(m_DrawCurrent==20)	//进行图形粘贴操作
	{
		OnSelectClear();
		xx1=m_xStart+blc*point.x;				//点中点的实际x坐标
		yy1=m_yStart+blc*(m_hScreen-point.y);	//点中点的实际y坐标
		if(pDoc->ReadClipBoard(xx1,yy1))
		{
//			for(int i=0;i<pDoc->n_GraphSelect;i++)		//删除图形
//				Delete(&ht,pDoc->GraphSelect[i].Lb,pDoc->GraphSelect[i].Index);
			//以下是记录删除图形这一操作,供逆操作时用
			pDoc->AddUndo(2,pDoc->n_GraphSelect,pDoc->GraphSelect);
			pDoc->n_GraphSelect=0;	//选中的图形元素为0
			Invalidate();
		}
	}
	CView::OnLButtonDown(nFlags, point);
}

//鼠标移动时被调用,ON_WM_MOUSEMOVE消息的映射函数
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CDrawDoc* pDoc = GetDocument();	//得到文档的指针
	CClientDC ddd(this);
	CPen pen(0,0,RGB(0,0,0));
	CPen* pOldPen=ddd.SelectObject(&pen);
	ddd.SetROP2(R2_NOT);	//选择反色的绘画模式
	int r;
	BOOL pb;
	float x1,y1;
	char p1[20];
	CMainFrame* pFrame=(CMainFrame*)(AfxGetApp()->m_pMainWnd);

	VPtoDP(point.x,point.y,&x1,&y1);
    sprintf(p1,"%f",x1);                  //将横坐标变为字符串
    pFrame->m_wndStatusBar.SetPaneText(2,p1,TRUE);//在状态条的第3个指示器写入
    sprintf(p1,"%f",y1);                  //将总坐标转为字符串
    pFrame->m_wndStatusBar.SetPaneText(3,p1,TRUE);//在状态条的第4个指示器写入

	if(m_DrawCurrent==1&&PushNumb==1)//如果是绘制直线并且已经按下第一点
	{
		if(mPointOld!=point)//如果鼠标的现在移动点与上一个点不相同
        //将起点到上一个移动点的直线擦除,绘制从起点到现在移动点的直线
		{
			ddd.MoveTo(mPointOrign); 
			ddd.LineTo(mPointOld);  //擦除上一条线
			ddd.MoveTo(mPointOrign);
			ddd.LineTo(point);      //画到鼠标移动点的直线
			mPointOld=point;  
		}
	}
	else if((m_DrawCurrent==2||m_DrawCurrent==3)&&PushNumb>=1)
	//如果是绘制连续直线或封闭多边形,并且已经按下第一点
	{
		if(mPointOld!=point)//如果鼠标的现在移动点与上一个点不相同
       //将上一个顶点到上一个移动点的直线擦除,绘制从上一个顶点到移动点的直线
		{
			ddd.MoveTo(mPointOrign); 
			ddd.LineTo(mPointOld);   //擦除原来的直线
			ddd.MoveTo(mPointOrign);
			ddd.LineTo(point);       //重画移动到点的直线
			mPointOld=point;  
		}
	}
	else if((m_DrawCurrent==4||m_DrawCurrent==5)&&PushNumb>=1)
	//如果是绘制圆或圆形区域,并且已经按下第一点
	{
		if(mPointOld!=point)//如果鼠标的现在移动点与上一个点不相同
        //将原来的圆擦掉,重新绘制圆
        {
			if(m_DrawCurrent==4)
				ddd.SelectStockObject(NULL_BRUSH); //如果是普通圆,设置不填充状态
			//上一个圆的半径  
			r=(int)sqrt(pow((float)(mPointOrign.x-mPointOld.x),2)+pow((float)(mPointOrign.y-mPointOld.y),2));
			//擦除上一个圆
			ddd.Ellipse(mPointOrign.x-r,mPointOrign.y-r,mPointOrign.x+r,mPointOrign.y+r);
			//移动点所在圆的半径
			r=(int)sqrt(pow((long)(mPointOrign.x-point.x),2)+pow((float)(mPointOrign.y-point.y),2));
			//绘制一个新圆
			ddd.Ellipse(mPointOrign.x-r,mPointOrign.y-r,mPointOrign.x+r,mPointOrign.y+r);
			mPointOld=point;  
		}
	}
	else if(m_DrawCurrent==6)	//在绘制圆弧操作
	{
		if(PushNumb==2&&mPointOld!=point)	//按下第二个点后
		{
			if(DrawArcYes>0)				//如果不是第一次画弧
				m_Arc1.Draw(&ddd,1,0,m_bColor); //擦掉原来的圆弧
			pb=jsarc(mPointOrign1,mPointOrign,point,&m_CircleX,&m_CircleY,
				&m_CircleR,&m_Angle1,&m_Angle2);	//计算目前圆弧的参数
			if(pb)	//如果三点能够形成圆弧,则以反色模式重新绘制实际是擦除圆弧
			{
				m_Arc1.Init(m_pColor,m_brColor,m_LineWide,m_LineType,
					m_Layer,m_CircleX,m_CircleY,m_CircleR,0,m_Angle1,m_Angle2);
				m_Arc1.Draw(&ddd,1,0,m_bColor);
			}
			DrawArcYes=pb;               //判断下一次绘制弧时要先删除弧
			mPointOld=point;
		}
	}
	else if((m_DrawCurrent==11||m_DrawCurrent==12||m_DrawCurrent==50)&&PushNumb==1)
	//如果是图形放大或移动并且按下了第一点
    {
		if(point!=mPointOld)		//如果鼠标移动了
		{
			if(m_DrawCurrent==11||m_DrawCurrent==50)	//如果是图形放大操作
			{
				ddd.SelectStockObject(NULL_BRUSH); //设置不填充状态
				//擦除原来的矩形
				ddd.Rectangle(mPointOrign.x,mPointOrign.y,mPointOld.x,mPointOld.y);
				//画新的矩形
				ddd.Rectangle(mPointOrign.x,mPointOrign.y,point.x,point.y);
			}
			else	//如果是图形移动操作
			{
				//擦除原来的橡皮线
				ddd.MoveTo(mPointOrign); ddd.LineTo(mPointOld);
				//画新的橡皮线
				ddd.MoveTo(mPointOrign); ddd.LineTo(point);
			}
			mPointOld=point;  //将本次移动点作为下次移动的上一点
		}
    }
	ddd.SelectObject(pOldPen); //选出画笔
	CView::OnMouseMove(nFlags, point);
}

//按下鼠标右键时被调用,ON_WM_RBUTTONDOWN消息的映射函数
void CDrawView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int r;
	CDrawDoc* pDoc = GetDocument();
	CClientDC ddd(this);
	CPen pen(0,0,RGB(0,0,0));				//定义一个画笔
	CPen* pOldPen=ddd.SelectObject(&pen);	//选择一个画笔
	ddd.SetROP2(R2_NOT);				//设置反色的绘画模式
	if(m_DrawCurrent==1&&PushNumb==1)	//如果正在绘制直线并且已经按下了起点
	{
		//将直线从屏幕上擦除并使绘制处于起始状态
		ddd.MoveTo(mPointOrign);
		ddd.LineTo(mPointOld);  //擦除屏幕上的拖动线
		PushNumb=0;             //结束绘制
		ReleaseCapture();       //释放捕捉的鼠标
	}
	else if((m_DrawCurrent==2||m_DrawCurrent==3)&&PushNumb>0)
	{
		//如果正在绘制连续直线或多边形区域并且已经按下了一次以上鼠标左键
		//擦除最后一段直线
		ddd.MoveTo(mPointOrign); 
		ddd.LineTo(mPointOld);
		if(m_DrawCurrent==2&&PushNumb>1) //如果顶点数大于1并在绘制直线
		{
			//保存连续直线并重新绘制连续直线
			int id=pDoc->GetPLineId();
			pDoc->AddPLine(m_pColor,m_brColor,m_LineWide,m_LineType,m_Layer,id,
				PushNumb,PointXyz,0)
				->Draw(&ddd,0,0,m_bColor);
			//以下是记录增加连续直线这一操作,供逆操作时用
			GraphUndo[0].Index=pDoc->GetMaxIndex(2);
			GraphUndo[0].Lb=2;
			pDoc->AddUndo(2,1,GraphUndo);
			ReleaseCapture();
		}
		else if(m_DrawCurrent==3&&PushNumb>2)//如果顶点数大于1并在绘制多边形区域
		{
			//保存封闭多边形并重新绘制封闭多边形
			int id=pDoc->GetPLineId();
			pDoc->AddPLine(m_pColor,m_brColor,m_LineWide,m_LineType,m_Layer,id,PushNumb,PointXyz,1)
				->Draw(&ddd,0,0,m_bColor);
			//以下是记录增加多边形区域这一操作,供逆操作时用
			GraphUndo[0].Index=pDoc->GetMaxIndex(2);
			GraphUndo[0].Lb=2;
			pDoc->AddUndo(2,1,GraphUndo);
			ReleaseCapture();
		}
		PushNumb=0;
		ReleaseCapture(); //释放捕捉的鼠标
	}

	else if((m_DrawCurrent==4||m_DrawCurrent==5)&&PushNumb>0)
	//如果是绘制圆或圆形区域,并且已经按下第一点
	{
		if(m_DrawCurrent==4)
			ddd.SelectStockObject(NULL_BRUSH); //如果是普通圆,设置不填充状态
		//得到上一个圆的半径 
		r=(int)sqrt(pow((float)(mPointOrign.x-mPointOld.x),2)+pow((float)(mPointOrign.y-mPointOld.y),2));
		//重画以擦除圆
		ddd.Ellipse(mPointOrign.x-r,mPointOrign.y-r,mPointOrign.x+r,mPointOrign.y+r);
		ReleaseCapture();  //释放捕捉的鼠标
		PushNumb=0;
	}
    
	else if(m_DrawCurrent==6&&PushNumb>0)//正在绘制弧并且按下了第一点
	{
		if(PushNumb==2)//已经按下两个点正在拖动弧
			m_Arc1.Draw(&ddd,1,0,m_bColor); //擦掉原来的弧
		PushNumb=0; //没有按中键
		ReleaseCapture();
	}

	else if((m_DrawCurrent==11||m_DrawCurrent==12||m_DrawCurrent==50)&&PushNumb==1)
	//如果在进行图形放大或图形移动并且按下了一次鼠标左键
	{
		ddd.SelectStockObject(NULL_BRUSH); //设置不填充状态
		if(m_DrawCurrent==11||m_DrawCurrent==50)     //如果是在“图形放大”,擦除矩形框
			ddd.Rectangle(mPointOrign.x,mPointOrign.y,point.x,point.y);
		else		//如果是在“图形移动”,擦除橡皮线
		{
			ddd.MoveTo(mPointOrign);
			ddd.LineTo(point);
		}
		ReleaseCapture();  //释放捕捉的鼠标
		PushNumb=0;        //放弃操作,使左键按下数置0
	}
	ddd.SelectObject(pOldPen);
	CView::OnRButtonDown(nFlags, point);
}


//“图形重画”菜单项的映射函数
void CDrawView::OnGraphRedraw() 
{
	CDrawDoc* pDoc = GetDocument();	//得到文档的指针
	Invalidate();
	pDoc->UpdateAllViews(this);
}

//“图形放大”菜单项的映射函数
void CDrawView::OnGraphZoom() 
{
	m_DrawCurrent=11;	//标识进行图形放大操作
	PushNumb=0;
}

//“图形移动”菜单项的对应函数
void CDrawView::OnGraphPan() 
{
	m_DrawCurrent=12;	//标识进行图形移动操作
	PushNumb=0;
}

//“重画上屏”菜单项的对应函数
void CDrawView::OnGraphUp() 
{
	CDrawDoc *pDoc=(CDrawDoc *)GetDocument();
	if(pDoc->m_CurrentScreen>0)	//如果不是第一屏
		pDoc->m_CurrentScreen--;
	//得到上一屏的图形参数并重画
	m_xStart=p_Screen[pDoc->m_CurrentScreen].sx;
	m_yStart=p_Screen[pDoc->m_CurrentScreen].sy;
	blc=p_Screen[pDoc->m_CurrentScreen].blc;
	InitVScroll();
	InitHScroll();
	Invalidate();
}

//“重画首屏”菜单项的对应函数
void CDrawView::OnGraphFirst() 
{
	CDrawDoc *pDoc=(CDrawDoc *)GetDocument();
	if(pDoc->m_CurrentScreen==0)
		return;
	m_xStart=p_Screen[0].sx;
	m_yStart=p_Screen[0].sy;
	blc=p_Screen[0].blc;
	pDoc->AddScreen(m_xStart,m_yStart,blc);
	InitVScroll();
	InitHScroll();
	Invalidate();
}

//“重画全屏”菜单项的对应函数
void CDrawView::OnGraphAll() 
{
	float minx,miny,maxx,maxy,bl1;
	CDrawDoc* pDoc = GetDocument();
	//捕捉光标,并使光标成沙漏等待光标
	//把最小值给非常大,把最大值给非常小,为了对变量进行初试化
	minx=(float)1E20;miny=(float)1E20;maxx=-(float)1E20;maxy=-(float)1E20;
	SetCapture();
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	BOOL pb=pDoc->GetRect(&minx,&miny,&maxx,&maxy);
	//将光标变为箭头形,放弃捕捉的光标
    SetCursor(LoadCursor(NULL,IDC_ARROW));
    ReleaseCapture();
	if(!pb)		//没有图形元素,程序返回
		return;
	bl1=(maxx-minx)/(m_wScreen-20);//横向的比例
	blc=(maxy-miny)/(m_hScreen-20);//实际纵向比例
	if(bl1>blc)blc=bl1;  //取较大的一个作为比例尺
	/*以下确定屏幕左下角的实际坐标,即在左侧和下侧都留了10点阵的区域
	(minx,miny)在屏幕的左下角向右10点阵同时向上10点阵处。*/
	m_xStart=minx-10*blc;
	m_yStart=miny-10*blc;
	//将全图的显示比例放在首屏,并把屏幕设为首屏
	p_Screen[0].sx=m_xStart;
	p_Screen[0].sy=m_yStart;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -