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

📄 drawview.cpp

📁 陈建春<用VC++开发GIS系统>源码.适合于GIS学习者,以及学习图形图象编程的朋友.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// The following command handler provides the standard keyboard
//  user interface to cancel an in-place editing session.  Here,
//  the container (not the server) causes the deactivation.
void CDrawView::OnCancelEditCntr()
{
	// Close any in-place active item on this view.
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL)
	{
		pActiveItem->Close();
	}
	ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}

// Special handling of OnSetFocus and OnSize are required for a container
//  when an object is being edited in-place.
void CDrawView::OnSetFocus(CWnd* pOldWnd)
{
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL &&
		pActiveItem->GetItemState() == COleClientItem::activeUIState)
	{
		// need to set focus to this item if it is in the same view
		CWnd* pWnd = pActiveItem->GetInPlaceWindow();
		if (pWnd != NULL)
		{
			pWnd->SetFocus();   // don't call the base class
			return;
		}
	}

	CView::OnSetFocus(pOldWnd);
}

//当视图的大小变化时被调用,cx,cy为变化后屏幕顶长、宽(像素)
void CDrawView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);
	CDrawDoc *pDoc=(CDrawDoc *)GetDocument();
	p_Screen=pDoc->m_Screen;
	m_wScreen=cx;	
	m_hScreen=cy;
    nXPage=m_hScreen/nScrollMin;  //横向一屏的滚动范围
    nYPage=m_wScreen/nScrollMin; //纵向一屏的滚动范围
	InitVScroll();
	InitHScroll();
}

/////////////////////////////////////////////////////////////////////////////
// CDrawView diagnostics

#ifdef _DEBUG
void CDrawView::AssertValid() const
{
	CView::AssertValid();
}

void CDrawView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CDrawDoc* CDrawView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawDoc)));
	return (CDrawDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDrawView message handlers

void CDrawView::InitVScroll()
{
	//得到滚动条的最大范围
	nVScrollMax=(int)(((float)m_hScreen*p_Screen[0].blc)/(blc*nScrollMin));
	//得到当前的滚动条范围
	nVScrollPos=nVScrollMax-(int)((m_yStart-p_Screen[0].sy)/(blc*nScrollMin));
	//设置滚动条最大范围和当前位置
	SetScrollRange(SB_VERT,0,nVScrollMax,TRUE);
	SetScrollPos(SB_VERT,nVScrollPos);//rrr.top=0;
	UpdateWindow();
}

void CDrawView::InitHScroll()
{
	
	//得到滚动条的最大范围
	nHScrollMax=(int)(((float)m_hScreen*p_Screen[0].blc/blc)/nScrollMin);
	//得到当前的滚动条范围
	nHScrollPos=(int)((m_xStart-p_Screen[0].sx)/blc/nScrollMin);
	//设置滚动条最大范围和当前位置
	SetScrollRange(SB_HORZ,0,nHScrollMax,TRUE);
	SetScrollPos(SB_HORZ,nHScrollPos);//rrr.top=0;
	UpdateWindow();

}

//选中菜单“绘制圆弧”时被调用
void CDrawView::OnDrawArc() 
{
	PushNumb=0;			//鼠标左键按下次数
	m_DrawCurrent=6;	//标识进行圆弧绘制操作
}

//选中菜单“绘制圆”时被调用
void CDrawView::OnDrawCircle() 
{
	PushNumb=0;			//鼠标左键按下次数
	m_DrawCurrent=4;	//标识进行圆绘制操作
}

//选中菜单“绘制圆形区域”时被调用
void CDrawView::OnDrawCircle1() 
{
	PushNumb=0;			//鼠标左键按下次数
	m_DrawCurrent=5;	//标识进行圆形区域操作
}

//选中菜单“绘制直线”时被调用
void CDrawView::OnDrawLine() 
{
	PushNumb=0;
	m_DrawCurrent=1;	//标识进行直线绘制操作
}

//选中菜单“绘制连续直线”时被调用
void CDrawView::OnDrawPline() 
{
	PushNumb=0;
	m_DrawCurrent=2;	//标识进行连续直线绘制操作
}

//选中菜单“绘制多边形区域”时被调用
void CDrawView::OnDrawRgn() 
{
	PushNumb=0;
	m_DrawCurrent=3;	//标识进行多边形区域绘制操作
}

//选中菜单“标注文字”时被调用
void CDrawView::OnDrawText() 
{
	PushNumb=0;
	m_DrawCurrent=7;	//标识进行文字标注操作
}

//在标注文字对话框中填入文字时被调用在屏幕上写文字
void CDrawView::DrawText()
{
	CClientDC ht(this);
	//以下从标注文字对话框中得到字体参数
	m_TextString=pTextDlg->m_Text;
	m_FontHeight=pTextDlg->m_FontHeight;
	m_FontWide=pTextDlg->m_FontWide;
	m_TextAngle=pTextDlg->m_Angle1;
	m_FontAngle=pTextDlg->m_Angle2;
	m_FontBetween=pTextDlg->m_FontBetween;
	//对一个字体类的参数重新进行辅值
	m_Text1->Init(m_pColor,m_brColor,m_LineWide,m_LineType,m_Layer,m_TextX,m_TextY
	,m_TextAngle,m_FontAngle,m_FontHeight,m_FontWide,m_FontBetween,0,m_TextString);
	m_Text1->Draw(&ht,0,0,m_bColor);//绘制标注信息
}

//按‘确定'退出标注文字对话框时被调用的函数,用来增加一个标注文字项
void CDrawView::DrawTextOnOk()
{
	CDrawDoc* pDoc = GetDocument();
    CClientDC ht(this);    
	int TextLong;
	PushNumb=0;
	m_TextString=pTextDlg->m_Text;		//得到标注的文字信息
	TextLong=m_TextString.GetLength();	//标注文字的长度
	if(TextLong>0)
	{
		//增加并重新绘制标注的文字
		int id=pDoc->GetTextId();
		pDoc->AddText(m_pColor,m_brColor,m_LineWide,m_LineType,m_Layer,id,m_TextX,
			m_TextY,m_TextAngle,m_FontAngle,m_FontHeight,m_FontWide,
			m_FontBetween,0,TextLong,m_TextString)
			->Draw(&ht,0,0,m_bColor);
		pTextDlg->m_Text.Empty();		//清空标注文字对话框中编辑框中顶文字
		pTextDlg->SendMessage(WM_INITDIALOG);
		//以下是记录增加标注信息这一操作,供逆操作时用
		GraphUndo[0].Index=pDoc->GetMaxIndex(5);//此标注文字的位置	
		GraphUndo[0].Lb=5;	//标注文字
		pDoc->AddUndo(2,1,GraphUndo);
		ReleaseCapture();	//释放捕捉的鼠标
	}
}

//按‘放弃'退出标注文字对话框时被调用的函数
void CDrawView::DrawTextOnCancel()
{
	pTextDlg->m_Text.Empty();	////清空标注文字对话框中编辑框中顶文字
	pTextDlg->SendMessage(WM_INITDIALOG);
}

//按下鼠标左键时被调用,ON_WM_LBUTTONDOWN消息的映射函数
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
    float r;
    float xx1,yy1,xx2,yy2;
	int x1,x2,y1,y2,Lb,Index,pbh;
	BOOL m_Fill;
	CDrawDoc* pDoc = GetDocument();	//得到文档指针
    CClientDC ht(this);    
    if(m_DrawCurrent==1)	//如果正在绘制直线
	{
		if(PushNumb==0)		//如果是第一次按下左鼠标键
		{
			PushNumb++;			//做标记表示按下鼠标左键一次
			mPointOrign=point;	//直线的第一点等于点中点
			mPointOld=point;	//记录本次点中点
			SetCapture();		//捕捉鼠标输入
		}
		else if(PushNumb==1) //第二次按下左鼠标键(即按下直线的结束点时)
		{
			//以下得到直线起终点的实际坐标
			VPtoDP(mPointOrign.x,mPointOrign.y,&xx1,&yy1);
			VPtoDP(point.x,point.y,&xx2,&yy2);
			int id=pDoc->GetLineId();	//得到直线的唯一识别号
			//增加一条直线并重新绘画此直线
			pDoc->AddLine(m_pColor,m_brColor,m_LineWide,m_LineType,m_Layer,id,
				xx1,yy1,xx2,yy2)
				->Draw(&ht,0,0,m_bColor);
			PushNumb=0;		//鼠标按键次数为0,重新进行直线的绘制
			//以下是记录增加直线这一操作,供逆操作时用
			GraphUndo[0].Index=pDoc->GetMaxIndex(1);//得到此直线的序号
			GraphUndo[0].Lb=1;	//直线
			pDoc->AddUndo(2,1,GraphUndo);
			ReleaseCapture();
		}
	}

	else if(m_DrawCurrent==2||m_DrawCurrent==3)//正在绘制连续直线或者多边形区域
	{
		//将点的坐标存入Pointxy中
		PointXyz[PushNumb].x=m_xStart+blc*point.x;
		PointXyz[PushNumb].y=m_yStart+blc*(m_hScreen-point.y);
		if(PushNumb==0)      //如果是第一次按下左鼠标键
		{
			SetCapture();     //捕捉鼠标
			mPointOrign=point;//原点等于点中点
			mPointOld=point;  //将前一个点设为点中点的坐标
		}
		else                 //二次以上按下鼠标左键时
		{
			mPointOrign=mPointOld; //将上一个点设为原点
			mPointOld=point;       //将点中点设为原点
		}
		PushNumb++;				//记录按下点的数目
	}

	else if(m_DrawCurrent==4||m_DrawCurrent==5)  //如果正在绘制普通圆或者填充圆
	{
		if(PushNumb==0)			//如果是第一次按下左鼠标键
		{
			mPointOrign=point;	//原点等于点中点
			mPointOld=point;	//上一个点也等于点中点
			PushNumb++;
			SetCapture();		//捕捉鼠标
		}
		else					//二次以上按下鼠标左键时
		{
			PushNumb=0;			//鼠标按键次数为0,重新进行直线的绘制
			//保存圆或填充圆
			r=(float)sqrt(pow((float)(mPointOrign.x-mPointOld.x),2)+pow((float)(mPointOrign.y-mPointOld.y),2));
			VPtoDP(mPointOrign.x,mPointOrign.y,&xx1,&yy1);
			if(m_DrawCurrent==4)	//如果是绘制一般圆
				m_Fill=0;
			else
				m_Fill=1;
			//保存圆并以覆盖模式重画圆
			int id=pDoc->GetCircleId();
			pDoc->AddCircle(m_pColor,m_brColor,m_LineWide,m_LineType,
				m_Layer,id,xx1,yy1,r,m_Fill)
				->Draw(&ht,0,0,m_bColor);
			ReleaseCapture();  //释放捕捉的鼠标 
			//以下是记录增加圆这一操作,供逆操作时用
			GraphUndo[0].Index=pDoc->GetMaxIndex(3);	//此圆的序号
			GraphUndo[0].Lb=3;	//类别是圆
			pDoc->AddUndo(2,1,GraphUndo);
			ReleaseCapture();
		}
	}

	else if(m_DrawCurrent==6)//正在绘制圆弧
	{
		if(PushNumb==0)			//第一次按下鼠标左键
		{
			SetCapture();
			DrawArcYes=0;
			mPointOrign1=point;	//记录圆弧第一点
			PushNumb++;
		}
		else if(PushNumb==1)	//第二次按下鼠标左键
        {
			mPointOrign=point;	//记录下圆弧的第二点
			PushNumb++;
		}
		else					//第三次按下鼠标键
		{
			//计算圆弧的特征参数
			jsarc(mPointOrign1,mPointOrign,point,&m_CircleX,&m_CircleY,
				&m_CircleR,&m_Angle1,&m_Angle2);
			//增加一个圆弧并重新绘制圆弧
			int id=pDoc->GetArcId();
			pDoc->AddArc(m_pColor,m_brColor,m_LineWide,m_LineType,m_Layer,id,
				m_CircleX,m_CircleY,m_CircleR,0,m_Angle1,m_Angle2)
				->Draw(&ht,0,0,m_bColor);
			PushNumb=0;         ////鼠标按键次数为0,重新进行圆弧的绘制
			ReleaseCapture();   //释放捕捉的鼠标
			//以下是记录增加圆弧这一操作,供逆操作时用
			GraphUndo[0].Index=pDoc->GetMaxIndex(4);	//此圆弧的序号
			GraphUndo[0].Lb=4;	//类别是圆弧
			pDoc->AddUndo(2,1,GraphUndo);
			ReleaseCapture();
		}
	}
	else if(m_DrawCurrent==7)	//进行标注文字的操作
	{
		VPtoDP(point.x,point.y,&m_TextX,&m_TextY);
		if(!pTextDlg)	//如果标注文字对话框不存在,产生对话框
		{
			//初始画形成一个标注文字对话框
			pTextDlg=new TextWriteDlg(this,m_TextString,m_FontHeight,m_FontWide,
				m_TextAngle,m_FontAngle,m_FontBetween);
			ASSERT(pTextDlg);
		}
		if(!(pTextDlg->IsOpen()))	//如果对话框没有打开
		{
			pTextDlg->Create(ID_WRITE_TEXT,this);
		}
		if(!(pTextDlg->IsVisible()))//如果对话框当前不可见
		{
			pTextDlg->ShowWindow(SW_SHOW);	//使标注文字对话框可见
		}
	}
	else if(m_DrawCurrent==11||m_DrawCurrent==12||m_DrawCurrent==50) //正在进行图形放大或图形移动
    {
		if(PushNumb==0) //如果第一次按下鼠标左键
        {
			mPointOrign=point; //原点等于点中点
			mPointOld=point;   //上一个点等于点中点
			PushNumb++;        //按键数增加1
			SetCapture();      //捕捉鼠标
		}
		else if(PushNumb==1)//第二次按下左键
		{
			if(m_DrawCurrent==11)  //图形放大
			{
				//得到左下点和右上点
				x1=min(mPointOrign.x,point.x);
				y1=max(mPointOrign.y,point.y);
				x2=max(mPointOrign.x,point.x);
				y2=min(mPointOrign.y,point.y); 
				//改变原点的坐标
				VPtoDP(x1,y1,&m_xStart,&m_yStart);
				//改变比例
				float bl1=(float)m_wScreen/(float)(x2-x1); //横向放大比例
				float bl2=(float)m_hScreen/(float)(y1-y2); //纵向放大比例
				if(bl2<bl1)
					bl1=bl2;		//取较小的变化比例
				if(bl1>0)   
					blc=blc/bl1;	//改变显示比例
				pDoc->AddScreen(m_xStart,m_yStart,blc);	//保存本屏的参数
				InitVScroll();
				InitHScroll();
				Invalidate();			//使图形重画
			}
			else if(m_DrawCurrent==12)	//图形移动操作
			{
				//改变原点(左下角点)的实际坐标
				m_xStart=m_xStart-blc*(point.x-mPointOrign.x);
				m_yStart=m_yStart+blc*(point.y-mPointOrign.y);
				pDoc->AddScreen(m_xStart,m_yStart,blc);	//保存本屏的参数
				InitVScroll();
				InitHScroll();
				Invalidate();			//使图形重画
			}
			else if(m_DrawCurrent==50)	//如果是插入OLE对象操作
			{
				//得到左下点和右上点
				x1=min(mPointOrign.x,point.x);
				y1=max(mPointOrign.y,point.y);
				x2=max(mPointOrign.x,point.x);
				y2=min(mPointOrign.y,point.y); 
				COleInsertDialog dlg;
				if (dlg.DoModal() != IDOK)
					return;
				BeginWaitCursor();
				CDrawCntrItem* pItem = NULL;
				TRY
				{
					pItem = new CDrawCntrItem(pDoc);
					ASSERT_VALID(pItem);
					if (!dlg.CreateItem(pItem))
						AfxThrowMemoryException();  // any exception will do
					ASSERT_VALID(pItem);

					if (dlg.GetSelectionType()==COleInsertDialog::createNewItem)
						pItem->DoVerb(OLEIVERB_SHOW, this);
					ASSERT_VALID(pItem);

⌨️ 快捷键说明

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