drawview.cpp

来自「VC做的矢量画图程序!」· C++ 代码 · 共 2,000 行 · 第 1/5 页

CPP
2,000 行
字号
	
	else if(m_DrawCurrent==30||m_DrawCurrent==100)			//进行鼠标点选图形操作
	{
		if(pDoc->n_GraphSelect==2000)	//如果选中的图形元素数是2000则不再选中
		{
			AfxMessageBox("最多只能选择2000个图形元素");
			return;
		}
		VPtoDP(point.x,point.y,&xx1,&yy1);
		float jl=blc*4;            //点中范围(4个像素的实际距离)
		if(m_DrawCurrent==100)
		pDoc->n_GraphSelect=0;

		  //以下对各种元素进行检查,计算是否点中(线,连续直线,圆和圆弧)
		BOOL pb=pDoc->PointSelect(xx1,yy1,jl,blc,&Lb,&Index,&pbh);
		 if(m_DrawCurrent==100)
		 {
		    if(pb)	//如果选中了图形元素,记录下选中顶图形元素,特殊显示此图形元素
			{  
			   BOOL pb1=pDoc->AddSelectList(Lb,Index,pbh);
			   if(pb1)
			   pDoc->DrawGraph(&ht,Lb,Index,0,1,m_bColor);
			   Invalidate();
			   pTree->ShowSelData();
			}
			else //没有对应记录
		    if(pBrowseDlg)
				if(pBrowseDlg->m_hWnd)
					if(pBrowseDlg->IsWindowVisible())
			        pBrowseDlg->ShowWindow(SW_HIDE);//隐藏对话框

		 }
		 else
		 {
			 if(pb)	//如果选中了图形元素,记录下选中顶图形元素,特殊显示此图形元素
			 {  
			   BOOL pb1=pDoc->AddSelectList(Lb,Index,pbh);
			    if(pb1)
				pDoc->DrawGraph(&ht,Lb,Index,0,1,m_bColor);
				Invalidate();
			 }
		     else	//如果没有选择图形元素,检查是否选中了OLE条目
			 {
			   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();
				 }
			   }
			}
		 }
		DispStatus("继续用鼠标点中要选择的图形元素");
	}

	else if(m_DrawCurrent==33)	//进行鼠标修改图形元素的图形数据
	{
		CString m_str;
		VPtoDP(point.x,point.y,&xx1,&yy1);
		float jl=blc*4;            //点中范围(4个像素的实际距离)
		BOOL pb=pDoc->PointSelect(xx1,yy1,jl,blc,&Lb,&Index,&pbh);
		if(pb)	//如果点中了图形元素
		{
			switch(Lb)
			{
				case 1:		//如果是直线
				{
					CLineDlg pDg1((CLine *)pDoc->GetGraph(1,Index));
					if(pDg1.DoModal()==IDOK)
						Invalidate();
					break;
				}
				case 2:		//如果是连续直线
				{
					CPLineDlg pDg1((CPline *)pDoc->GetGraph(2,Index));
					if(pDg1.DoModal()==IDOK)
						Invalidate();
					break;
				}
				case 3:		//如果是圆
				{	
					CCircleDlg pDg1((CCircle *)pDoc->GetGraph(3,Index));
					if(pDg1.DoModal()==IDOK)
						Invalidate();
					break;
				}
				case 4:		//如果是圆弧
				{
					CArcDlg pDg1((CArc *)pDoc->GetGraph(4,Index));
					if(pDg1.DoModal()==IDOK)
						Invalidate();
					break;
				}
				case 5:		//如果是标注文本
				{
					CTextDlg pDg1((CText *)pDoc->GetGraph(5,Index));
					if(pDg1.DoModal()==IDOK)
						Invalidate();
					break;
				}
				case 6:		//如果是图例
				{
					CTagDlg pDg1(pDoc,(CTag *)pDoc->GetGraph(6,Index));
					if(pDg1.DoModal()==IDOK)
						Invalidate();
					break;
				}
			}
		}
		DispStatus("继续用鼠标点中要修改数据的图形元素");
	}
	else if(m_DrawCurrent==19)	//如果正在进行移动选中的图形元素操作
	{
		if(PushNumb==0)			//第一次按下鼠标左键
		{
			x_Move=0;
			y_Move=0;
			mPointOrign=point;	//原点等于点中点
			mPointOld=point;	//上一个点等于点中点
			PushNumb++;
			SetCapture();
		}
		else if(PushNumb==1)	//第二次按下鼠标左键
		{
			PushNumb=0;			//完成操作,左键按下数置0
			ReleaseCapture();	//释放捕捉的鼠标
			m_DrawCurrent=0;
			Invalidate();
		}
	}
	else if(m_DrawCurrent==20)	//进行图形粘贴操作
	{
		OnSelectClear();
		VPtoDP(point.x,point.y,&xx1,&yy1);
		if(pDoc->ReadClipBoard(xx1,yy1))
		{
			//以下是记录粘贴图形这一操作,供逆操作时用
			pDoc->AddUndo(2,pDoc->n_GraphSelect,pDoc->GraphSelect);
			pDoc->n_GraphSelect=0;	//选中的图形元素为0
			Invalidate();
		}
		DispStatus("请用鼠标点中另外一个粘贴点");
	}
	else if(m_DrawCurrent==40)	//将选择的图形元素形成一个图形块
	{
		VPtoDP(point.x,point.y,&xx1,&yy1);
		pDoc->OnBlockAdd(xx1,yy1);
		PushNumb=0;
		m_DrawCurrent=0;
		OnSelectClear();
		DispStatus("请选择操作菜单");
	}
	else if(m_DrawCurrent==41)	//鼠标绘制图形块的插入点
	{
		VPtoDP(point.x,point.y,&xx1,&yy1);
		pDoc->x_Insert=xx1;
		pDoc->y_Insert=yy1;
		PushNumb=0;
		m_DrawCurrent=0;
		DispStatus("请选择操作菜单");
		Invalidate();
	}
	CView::OnLButtonDown(nFlags, point);
}


//鼠标移动时被调用,ON_WM_MOUSEMOVE消息的映射函数
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) 
{
	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||m_DrawCurrent>=81&&m_DrawCurrent<=84)&&PushNumb>=1)
	//如果是绘制连续直线或封闭多边形,并且已经按下第一点
	{
		if(mPointOld!=point)//如果鼠标的现在移动点与上一个点不相同
       //将上一个顶点到上一个移动点的直线擦除,绘制从上一个顶点到移动点的直线
		{
			ddd.MoveTo(mPointOrign); 
			ddd.LineTo(mPointOld);   //擦除原来的直线
			ddd.MoveTo(mPointOrign);
			ddd.LineTo(point);       //重画移动到点的直线
			mPointOld=point;  
		}
	}

	else if(m_DrawCurrent==300&&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||m_DrawCurrent>=71&&m_DrawCurrent<=74)&&PushNumb>=1)
	//如果是绘制圆或圆形区域,并且已经按下第一点
	{
		if(mPointOld!=point)//如果鼠标的现在移动点与上一个点不相同
        //将原来的圆擦掉,重新绘制圆
        {
			if(m_DrawCurrent==4||m_DrawCurrent>=71&&m_DrawCurrent<=74)
				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,0,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==8&&PushNumb>=1)//绘制图例并且已经按下了高度的第一点
	{
		if(mPointOld!=point)//如果鼠标的现在移动点与上一个点不相同
		//将上一个顶点到上一个移动点的直线擦除,绘制从上一个顶点到移动点的直线
		{
			if(PushNumb==1)//拖动直线
			{
				ddd.MoveTo(mPointOrign); 
				ddd.LineTo(mPointOld);   //擦除原来的直线
				ddd.MoveTo(mPointOrign);
				ddd.LineTo(point);       //重画移动到点的直线
				mPointOld=point;  
			}
			else if(PushNumb==2)//拖动图例
			{
				
				VPtoDP(mPointOld.x,mPointOld.y,&x1,&y1);
				pBlock->Draw(&ddd,x1,y1,x_Scale,y_Scale,1,0);
				VPtoDP(point.x,point.y,&x1,&y1);
				pBlock->Draw(&ddd,x1,y1,x_Scale,y_Scale,1,0);
				mPointOld=point;
			}
		}
	}
	else if(m_DrawCurrent==9&&PushNumb>=1)	//如果是绘制表格域并且按下了第一个顶点
    {
		if(point!=mPointOld)	//如果鼠标移动了
		{
			ddd.SelectStockObject(NULL_BRUSH);	//设置不填充状态
			ddd.Rectangle(mPointOrign.x,mPointOrign.y,mPointOld.x,mPointOld.y);	//擦除原来的矩形
			ddd.Rectangle(mPointOrign.x,mPointOrign.y,point.x,point.y);		//画新的矩形
			mPointOld=point;	//将本次移动点作为下次移动的上一点
		}
    }
	else if((m_DrawCurrent==11||m_DrawCurrent==50||m_DrawCurrent>=61&&m_DrawCurrent<=63)&&PushNumb==1)
	//如果是图形放大或移动并且按下了第一点
    {
		if(point!=mPointOld)		//如果鼠标移动了
		{
			if(m_DrawCurrent==11||m_DrawCurrent==50||m_DrawCurrent>=61&&m_DrawCurrent<=63)	//如果是图形放大操作
			{
				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;  //将本次移动点作为下次移动的上一点
		}
    }
	else if(m_DrawCurrent==19)	//如果在进行移动选择的图形元素这个操作
	{
		if(point!=mPointOld&&PushNumb>0)		//如果鼠标移动了
		{
			x1=VLtoDL(point.x-mPointOld.x);
			y1=-VLtoDL(point.y-mPointOld.y);
			x_Move+=x1;			//记录总的横向移动距离(供放弃操作使用)
			y_Move+=y1;			//记录总的纵向移动距离(供放弃操作使用)
			for(int i=0;i<pDoc->n_GraphSelect;i++)	//特殊显示选中的图形元素
				pDoc->DrawGraph(&ddd,pDoc->GraphSelect[i].Lb,pDoc->GraphSelect[i].Index,1,1,0);
			for(i=0;i<pDoc->n_GraphSelect;i++)
			{
				CDraw* pDraw=pDoc->GetGraph(pDoc->GraphSelect[i].Lb,pDoc->GraphSelect[i].Index);
				pDraw->Move(x1,y1);	//移动图形元素的坐标
				pDraw->Draw(&ddd,1,1,0);
			}
		}
		mPointOld=point;
	}
	ddd.SelectObject(pOldPen); //选出画笔
	CView::OnMouseMove(nFlags, point);
}

//按下鼠标右键时被调用,ON_WM_RBUTTONDOWN消息的映射函数
void CDrawView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	int r;
	float x1,y1,x2,y2;
	float xx1,yy1,xx2,yy2;
	int id;
	BOOL bSelect;
	CDrawDoc* pDoc = GetDocument();
	CClientDC ddd(this);
	if(PushNumb==0)
	{
		DispStatus("请选择操作菜单");
		m_DrawCurrent=0;
		return;
	}
	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();       //释放捕捉的鼠标
		DispStatus("请用鼠标点中直线的起点");
	}

	else if((m_DrawCurrent==2||m_DrawCurrent==3)&&PushNumb>0)
	{
		//如果正在绘制连续直线或多边形区域并且已经按下了一次以

⌨️ 快捷键说明

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