drawview.cpp

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

CPP
2,000
字号

void CDrawView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	int mPageHeight,mPageWidth,nPage;
	POINT point;
	m_MapMode=2;
	pDC->SetMapMode(m_MapMode);
	//整个图形左下角的坐标
	xLeft=p_Screen[0].sx;
	yBottom=p_Screen[0].sy;
	//整个图形右上角的坐标为
	xRight=xLeft+p_Screen[0].blc*m_wScreen;
	yTop=yBottom+p_Screen[0].blc*m_hScreen;
	//图形的横向和纵向的幅度为
	xWide=xRight-xLeft;
	yHigh=yTop-yBottom;
	point.y=pDC->GetDeviceCaps(VERTRES);  //得到设备竖直方向的像素数
	point.x=pDC->GetDeviceCaps(HORZRES);   //得到设备水平方向的像素数
	//pDC->DPtoLP(&point);
	pDC->DPtoLP(&(pInfo->m_rectDraw));
	mPageHeight=point.y;
	mPageWidth=point.x;
//	mPageHeight=abs(pInfo->m_rectDraw.top-pInfo->m_rectDraw.bottom);
//	mPageWidth=pInfo->m_rectDraw.right-pInfo->m_rectDraw.left;

	//每页的横向和纵向大小
	xPage=blc*mPageWidth;                     //每页的实际宽度
	yPage=blc*mPageHeight;                    //每页的实际高度
	nPageX=(int)(xWide/xPage)+(xWide>xPage*(int)(xWide/xPage));//横向页数
	nPageY=(int)(yHigh/yPage)+(yHigh>yPage*(int)(yHigh/yPage));//纵向页数
	nPage=nPageX*nPageY;       //总页数
	pInfo->SetMinPage(1);      //设置最小页号
	pInfo->SetMaxPage(nPage);  //设置最大页号
	m_hScreen1=m_hScreen;
	m_wScreen1=m_wScreen;
	m_hScreen=mPageHeight;    //显示窗口的高度
	m_wScreen=mPageWidth;     //显示窗口的宽度
}

void CDrawView::OnEndPrinting(CDC* pDC, CPrintInfo* /*pInfo*/)
{
	CDrawDoc* pDoc = GetDocument();
	m_xStart=p_Screen[pDoc->m_CurrentScreen].sx;
	m_yStart=p_Screen[pDoc->m_CurrentScreen].sy;
	// TODO: add cleanup after printing
	m_hScreen=m_hScreen1;
	m_wScreen=m_wScreen1;
	m_MapMode=1;
}

void CDrawView::OnDestroy()
{
   CView::OnDestroy();
   COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
   if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
   {
      pActiveItem->Deactivate();
      ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
   }
}


/////////////////////////////////////////////////////////////////////////////
// OLE Client support and commands

BOOL CDrawView::IsSelected(const CObject* pDocItem) const
{
	// The implementation below is adequate if your selection consists of
	//  only CDrawCntrItem objects.  To handle different selection
	//  mechanisms, the implementation here should be replaced.
	// TODO: implement this function that tests for a selected OLE client item
	return pDocItem == m_pSelection;
}

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);
}

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 = GetDocument();
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL)
		pActiveItem->SetItemRects();
	//记录改变后的屏幕大小
	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()
{
	CDrawDoc* pDoc = GetDocument();
	//得到滚动条的最大范围
   // nVScrollMax=(int)(((float)m_hScreen*p_Screen[pDoc->m_CurrentScreen1].blc)/(blc*nScrollMin));
	//得到当前的滚动条范围
    //nVScrollPos=nVScrollMax-(int)((m_yStart-p_Screen[pDoc->m_CurrentScreen1].sy)/(blc*nScrollMin))-1;
	//设置滚动条最大范围和当前位置
	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;	//标识进行圆弧绘制操作
	DispStatus("请用鼠标点中圆弧的起点");
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);
}

//选中菜单“绘制圆”时被调用
void CDrawView::OnDrawCircle() 
{
	PushNumb=0;			//鼠标左键按下次数
	m_DrawCurrent=4;	//标识进行圆绘制操作
	DispStatus("请用鼠标点中圆的圆心");
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);
}

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

//选中菜单“绘制直线”时被调用
void CDrawView::OnDrawLine() 
{
	PushNumb=0;
	m_DrawCurrent=1;	//标识进行直线绘制操作
	DispStatus("请用鼠标点中直线的起点");
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);
}

//选中菜单“绘制连续直线”时被调用
void CDrawView::OnDrawPline() 
{   
	PushNumb=0;
	m_DrawCurrent=2;	//标识进行连续直线绘制操作
	DispStatus("鼠标左键点中连续直线的顶点,右键完成绘制");
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);
}

//选中菜单“绘制多边形区域”时被调用
void CDrawView::OnDrawRgn() 
{
	PushNumb=0;
	m_DrawCurrent=3;	//标识进行多边形区域绘制操作
	DispStatus("请用鼠标点中多边形区域的一个顶点");
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);
}

//选中菜单“标注文字”时被调用
void CDrawView::OnDrawText() 
{
	PushNumb=0;
	m_DrawCurrent=7;	//标识进行文字标注操作
	DispStatus("请用鼠标点中标注文本的起始点");
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);
}

//开始绘制图例的函数,“绘制图例”菜单项的消息处理函数
void CDrawView::OnDrawTag() 
{
	CDrawDoc* pDoc = GetDocument();
	PushNumb=0;
	if(pDoc->BlockIndex<0)
		return;
	pBlock=pDoc->GetBlock(pDoc->BlockIndex);
	m_DrawCurrent=8;	//标识进行文字标注操作
	DispStatus("请用鼠标点中图例高度的起点");
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);
}



//在标注文字对话框中填入文字时被调用在屏幕上写文字
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);//绘制标注信息
	DispStatus("请用鼠标点中图例高度的起点");
}

//按‘确定'退出标注文字对话框时被调用的函数,用来增加一个标注文字项
void CDrawView::DrawTextOnOk()
{
	CDrawDoc* pDoc = GetDocument();
    CClientDC ht(this);    
	int TextLong,id;
	PushNumb=0;
	m_TextString=pTextDlg->m_Text;		//得到标注的文字信息
	TextLong=m_TextString.GetLength();	//标注文字的长度
	if(TextLong>0)
	{
		//增加并重新绘制标注的文字
		if(pDoc->m_DrawEdit==0)
			id=pDoc->GetGraphID(5);
		else
			id=0;
		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->GetGraphUpperBound(5);//此标注文字的位置	
		GraphUndo[0].Lb=5;	//标注文字
		ReleaseCapture();	//释放捕捉的鼠标
		pDoc->AddUndo(2,1,GraphUndo);
	}
	DispStatus("请用鼠标点中标注文本的起始点");
}

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

//“删除图形”菜单项的对应函数,用来删除鼠标选中的图形
void CDrawView::OnSelectDelete()
{
	CDrawDoc* pDoc = GetDocument();
	CClientDC ht(this);
	CDraw * pDraw;
	CString strSql;
	CString str;
	for(int i=0;i<pDoc->n_GraphSelect;i++)	//删除选中的图形
	{
		pDraw=pDoc->GetGraph(pDoc->GraphSelect[i].Lb,pDoc->GraphSelect[i].Index);
		if(pDraw->m_Layer==1||pDraw->m_Layer==2||pDraw->m_Layer==3)
		{
			CRecordset * pSet=new CRecordset(&((CDrawApp*) AfxGetApp())->m_pdatabase);
			strSql.Format("select * from LINKINFO where element_id=%d and graph_id=%d",pDraw->m_id_only,pDraw->m_Lb);
			pSet->Open(CRecordset::dynaset,_T(strSql));
			if(!pSet->IsBOF())
			{
				str.Format("%d",pDraw->m_id_only);
				if(pDraw->m_Lb==1)
				{					
				    if( AfxMessageBox("删除直线id为"+str+"的记录将永久删除该直线与记录的连接,\n是否删除该线段?",MB_YESNO,0)==IDNO)
                    continue;
				}
				else if(pDraw->m_Lb==2)
				{
					if( AfxMessageBox("删除连续直线id为"+str+"的记录将永久删除该连续直线与记录的连接,\n是否删除该线段?",MB_YESNO,0)==IDNO)
                    continue;
				}
				strSql.Format("delete from  LINKINFO where element_id=%d and graph_id=%d",pDraw->m_id_only,pDraw->m_Lb);
                ((CDrawApp*) AfxGetApp())->m_pdatabase.ExecuteSQL(_T(strSql));
				
			}
		}
		Delete(&ht,pDoc->GraphSelect[i].Lb,pDoc->GraphSelect[i].Index);
	}
	    //以下是记录删除图形这一操作,供逆操作时用
	pDoc->AddUndo(3,pDoc->n_GraphSelect,pDoc->GraphSelect);
	ReleaseCapture();
	pDoc->n_GraphSelect=0;	//选中的图形元素为0
	if(pDoc->b_IsOleSelect)
	{
		POSITION pos=pDoc->GetStartPosition();
		while(pos!=NULL)
		{
			CDrawCntrItem *pItem=(CDrawCntrItem *)pDoc->GetNextClientItem(pos);
			if(pItem!=NULL)
			{
				if(pItem->b_Select)
				{
					pDoc->RemoveItem(pItem);
					delete pItem;
					m_pSelection =NULL;   // set selection to last inserted item
				}
			}
		}
	    pDoc->UpdateAllViews(this);	
	}
   Invalidate();
}

//“Cut"菜单项的对应函数,用来删除鼠标选中的图形并将删除的图形放在剪裁板
void CDrawView::OnEditCut() 
{
	CClientDC ht(this);
	CDrawDoc* pDoc = GetDocument();
	short nGraphCut;
	nGraphCut=0;
	for(int i=0;i<pDoc->n_GraphSelect;i++)	//以下经过处理,只能剪裁直线等5种图形元素(不能剪裁表格域和图例)
	{
		if(pDoc->GraphSelect[i].Lb<=5)	//如果是直线、圆、圆形区域、连续直线和标注文本等5种图形元素)
			pDoc->GraphSelect[nGraphCut++]=pDoc->GraphSelect[i];
	}
	pDoc->n_GraphSelect=nGraphCut;
	if(pDoc->WriteClipBoard())	//如果将图形元素写入剪裁板成功
	{
		for(int i=0;i<pDoc->n_GraphSelect;i++)		//删除图形
			Delete(&ht,pDoc->GraphSelect[i].Lb,pDoc->GraphSelect[i].Index);
		//以下是记录删除图形这一操作,供逆操作时用
		pDoc->AddUndo(3,pDoc->n_GraphSelect,pDoc->GraphSelect);
		pDoc->n_GraphSelect=0;	//选中的图形元素为0
		DispStatus("操作成功,请选择操作菜单");
	}
	pDoc->n_GraphSelect=0;
}

//移动选中的图形元素
void CDrawView::OnEditMove() 
{
	DispStatus("请用鼠标点中移动的相对基点");
	m_DrawCurrent=19;
	PushNumb=0;
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (long)m_hcurCross);

⌨️ 快捷键说明

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