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 + -
显示快捷键?