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