📄 drawview.cpp
字号:
p_Screen[0].blc=blc;
pDoc->m_CurrentScreen=0;
InitVScroll();
InitHScroll();
Invalidate();
}
//“鼠标选中”菜单项的对应函数
void CDrawView::OnSelectMouse()
{
m_DrawCurrent=30; //标识进行图形选中操作
PushNumb=0;
}
//“放弃选中”菜单项的对应函数,用来放弃所作的选择
void CDrawView::OnSelectClear()
{
CDrawDoc* pDoc = GetDocument();
CClientDC ht(this);
for(int i=0;i<pDoc->n_GraphSelect;i++) //将选中的图形元素原样进行绘制
pDoc->DrawGraph(&ht,pDoc->GraphSelect[i].Lb,pDoc->GraphSelect[i].Index,0,0,m_bColor);
pDoc->n_GraphSelect=0;
if(pDoc->b_IsOleSelect)
{
POSITION pos=pDoc->GetStartPosition();
while(pos!=NULL)
{
CDrawCntrItem *pItem=(CDrawCntrItem *)pDoc->GetNextClientItem(pos);
if(pItem!=NULL)
pItem->b_Select=FALSE;
}
pDoc->b_IsOleSelect=0;
Invalidate();
}
}
//用来删除一个图形元素的函授数
//Lb-删除图形的类别 Index-删除图形顶序列号
void CDrawView::Delete(CDC* pDC,int Lb,int Index)
{
float x1,y1,x2,y2;
CDrawDoc* pDoc = GetDocument();
if(Lb==1) //如果是直线,得到直线指针并以屏幕底色重画达到删除的效果
{
CLine* p_Line=pDoc->GetLine(Index);
p_Line->Draw(pDC,0,2,m_bColor);
p_Line->Delete(1); //做删除标识
}
else if(Lb==2) //如果是连续直线或多边形
{
CPline* p_PLine=pDoc->GetPLine(Index); //得到连续直线(多边形)的指针
if(p_PLine->IsPLine()) //如果是连续直线,以屏幕底色重画达到删除的效果
p_PLine->Draw(pDC,0,2,m_bColor);
else //如果是多边形区域
{
p_PLine->GetRect(&x1,&y1,&x2,&y2); //得到多边形区域的边界矩形
ReDrawRect(x1,y1,x2,y2); //重画多边形区域所在顶区域
}
p_PLine->Delete(1); //做删除标识
}
else if(Lb==3) //如果是圆或圆形区域
{
CCircle* p_Circle=pDoc->GetCircle(Index);//得到圆(圆形区域)的指针
if(p_Circle->IsCircle()) //如果是圆,则以屏幕底色进行重画
p_Circle->Draw(pDC,0,2,m_bColor);
else //如果是圆形区域,则得到其边界矩形并重画这个区域
{
p_Circle->GetRect(&x1,&y1,&x2,&y2);
ReDrawRect(x1,y1,x2,y2);
}
p_Circle->Delete(1); //做删除标识
}
else if(Lb==4) //如果是圆弧,则以屏幕底色进行重画
{
CArc* p_Arc=pDoc->GetArc(Index); //得到圆弧的指针
p_Arc->Draw(pDC,0,2,m_bColor);
p_Arc->Delete(1); //做删除标识
}
else if(Lb==5) //如果是标注文字,则得到其边界矩形并重画这个区域
{
CText* p_Text=pDoc->GetText(Index); //得到标注文字的指针
p_Text->GetRect(&x1,&y1,&x2,&y2);
p_Text->Delete(1); //做删除标识
ReDrawRect(x1,y1,x2,y2);//重画屏幕区域
}
}
//此函数用来重画由点(X1,Y1)和点(X2,Y2)确定的区域
void CDrawView::ReDrawRect(float X1, float Y1, float X2, float Y2)
{
float xx1,xx2,yy1,yy2;
CRect r1;
xx1=m_xStart; xx2=m_xStart+blc*m_wScreen;
yy1=m_yStart; yy2=m_yStart+blc*m_hScreen;
//得到区域与视图区域相交的矩形
BOOL IsCross=RectCross(&xx1,&yy1,&xx2,&yy2,X1,Y1,X2,Y2);
if(IsCross) //如果相交,则重画这一区域
{
//以下得到这个区域顶像素坐标
r1.left=(int)((xx1-m_xStart)/blc)-1;
r1.right=(int)((xx2-m_xStart)/blc)+1;
r1.top=m_hScreen-(int)((yy2-m_yStart)/blc)-1;
r1.bottom=m_hScreen-(int)((yy1-m_yStart)/blc)+1;
InvalidateRect(r1);
}
}
//此函数用来计算由(*x1,*y1),(*x2,*y2)和(xx1,yy1),(xx2,yy2)决定的两个区域的相交区域
//返回:TURE,两区域相交,相交区域由(*x1,*y1),(*x2,*y2)决定
BOOL CDrawView::RectCross(float* x1,float* y1,float* x2,float* y2,float xx1,
float yy1,float xx2,float yy2)
{
float m_X1,m_Y1,m_X2,m_Y2;
m_X1=*x1; m_Y1=*y1; m_X2=*x2 ;m_Y2=*y2;
if(m_X1>xx2||m_X2<xx1||m_Y1>yy2||m_Y2<yy1) //两个矩形区域不相交
return FALSE; //如不相交函数返回0
else //两个矩形相交,得到相交矩形的坐标
{
*x1=max(m_X1,xx1);
*y1=max(m_Y1,yy1);
*x2=min(m_X2,xx2);
*y2=min(m_Y2,yy2);
return TRUE; //如果相交就返回1
}
}
//“删除图形”菜单项的对应函数,用来删除鼠标选中的图形
void CDrawView::OnSelectDelete()
{
CDrawDoc* pDoc = GetDocument();
CClientDC ht(this);
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);
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);
}
}
//“Cut"菜单项的对应函数,用来删除鼠标选中的图形并将删除的图形放在剪裁板
void CDrawView::OnEditCut()
{
CClientDC ht(this);
CDrawDoc* pDoc = GetDocument();
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
}
}
void CDrawView::OnEditPaste()
{
m_DrawCurrent=20;
PushNumb=0;
}
//“Copy"菜单项的对应函数,用来将选中的图形放在剪裁板
void CDrawView::OnEditCopy()
{
CDrawDoc* pDoc = GetDocument();
pDoc->WriteClipBoard(); //将图形写入剪裁板
}
//“Undo"菜单项的对应函数,用来实现完全的逆操作
void CDrawView::OnEditUndo()
{
CDrawDoc* pDoc = GetDocument();
CClientDC ht(this);
pDoc->OnEditUndo(); //进行一步逆操作
pDoc->UpdateAllViews(this); //重画所有视图
}
void CDrawView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
short nScrollInc;
int nNewPos;
CRect r1;
switch(nSBCode)
{
case SB_TOP:
nScrollInc=-nHScrollPos;
break;
case SB_BOTTOM:
nScrollInc=nHScrollMax-nHScrollPos;
break;
case SB_LINEUP:
nScrollInc=-nXLine;
break;
case SB_LINEDOWN:
nScrollInc=nXLine;
break;
case SB_PAGEUP:
nScrollInc=-nXPage;
break;
case SB_PAGEDOWN:
nScrollInc=nXPage;
break;
case SB_THUMBPOSITION:
nScrollInc=nPos-nHScrollPos;
break;
default:
nScrollInc=0;
}
nNewPos=max(0,min(nHScrollPos+nScrollInc,nHScrollMax));
nScrollInc=nNewPos-nHScrollPos;
if(nScrollInc) //如果产生了滚动
{
nHScrollPos=nNewPos; //设定新的滚动位置
SetScrollPos(SB_HORZ,nHScrollPos);
UpdateWindow();//使滚动条的位置改动在屏幕上实现
m_xStart=m_xStart+blc*nScrollInc*nScrollMin;//调整纵坐标使图形产生滚动
GetClientRect(&r1); //得到客户区的矩形边界
if(abs(nScrollInc)*nScrollMin<r1.right) //如果滚动后的屏幕与滚动前有重叠
{
if(nScrollInc>0) //如果是图形向上滚动
r1.left=nScrollInc*nScrollMin; //得到滚动屏幕上重叠区域的矩形
else //如果图形向下滚动
r1.right=r1.right-nScrollInc*nScrollMin; //得到重叠区域的矩形
ScrollWindow(-nScrollInc*nScrollMin,0,r1); //滚动重叠的区域
if(nScrollInc>0) //如果是向上滚动
r1.left=r1.right-nScrollInc*nScrollMin; //得到需要重画的区域
else //如果是向下滚动
r1.right=-nScrollInc*nScrollMin; //得到需要重画的区域
InvalidateRect(r1,0); //对图形进行局部重画
}
else //如果滚动后的区域与滚动前的区域没有重叠,则全屏重画
Invalidate();
//恢复矩形rr原来的坐标
// r.left=0;
// r.right=ScreenWide;
}
/*
if(nScrollInc)
{
nHScrollPos=nNewPos;
SetScrollPos(SB_HORZ,nHScrollPos);
UpdateWindow();
startx=startx+blc*nScrollInc*nScrollMin;
Screenxy[numb][0]=startx;
Invalidate();
r.top=0;
r.bottom=ScreenHigh;
}*/
CView::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CDrawView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
short nScrollInc;
int nNewPos;
CRect r1;
switch(nSBCode) //判断按键位置
{
case SB_TOP: //如果将滚动条滚动到顶部
nScrollInc=-nVScrollPos; //得到相对滚动范围
break;
case SB_BOTTOM: //如果将滚动条滚动到底部
nScrollInc=nVScrollMax-nVScrollPos; //得到相对的滚动范围
break;
case SB_LINEUP: //如果按了滚动条中的向上的按键
nScrollInc=-nYLine; //得到相对滚动位置
break;
case SB_LINEDOWN: //如果按中了向下的按键
nScrollInc=nYLine; //得到相对的滚动位置
break;
case SB_PAGEUP: //如果按中了中间活动按钮的上部区域
nScrollInc=-nYPage; //得到相对的滚动位置
break;
case SB_PAGEDOWN: //如果按中了中间活动钮的下部位置
nScrollInc=nYPage; //得到相对的滚动位置
break;
case SB_THUMBPOSITION: //如果用鼠标拖动中间活动钮到一个位置
nScrollInc=nPos-nVScrollPos; //通过信息处理函数得到的按钮位置得到相对移动位置
break;
default:
nScrollInc=0;
}
//进行滚动边界检查,得到实际的滚动位置(不能超出滚动条的滚动范围)
nNewPos=max(0,min(nVScrollPos+nScrollInc,nVScrollMax));
//得到实际的相对滚动范围
nScrollInc=nNewPos-nVScrollPos;
if(nScrollInc) //如果产生了滚动
{
nVScrollPos=nNewPos; //设定新的滚动位置
SetScrollPos(SB_VERT,nVScrollPos);
UpdateWindow();//使滚动条的位置改动在屏幕上实现
m_yStart=m_yStart-blc*nScrollInc*nScrollMin;//调整纵坐标使图形产生滚动
GetClientRect(&r1); //得到客户区的矩形边界
if(abs(nScrollInc)*nScrollMin<r1.bottom) //如果滚动后的屏幕与滚动前有重叠
{
if(nScrollInc>0) //如果是图形向上滚动
r1.top=nScrollInc*nScrollMin; //得到滚动屏幕上重叠区域的矩形
else //如果图形向下滚动
r1.bottom=r1.bottom+nScrollInc*nScrollMin; //得到重叠区域的矩形
ScrollWindow(0,-nScrollInc*nScrollMin,r1); //滚动重叠的区域
if(nScrollInc>0) //如果是向上滚动
r1.top=r1.bottom-nScrollInc*nScrollMin; //得到需要重画的区域
else //如果是向下滚动
r1.bottom=-nScrollInc*nScrollMin; //得到需要重画的区域
InvalidateRect(r1,0); //对图形进行局部重画
//pbdy=1;
}
else //如果滚动后的区域与滚动前的区域没有重叠,则全屏重画
Invalidate();
}
CView::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CDrawView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch(nChar)
{
case VK_HOME:
OnHScroll(SB_PAGEUP,0,NULL);
break;
case VK_END:
OnHScroll(SB_PAGEDOWN,0,NULL);
break;
case VK_PRIOR:
OnVScroll(SB_PAGEUP,0,NULL);
break;
case VK_NEXT:
OnVScroll(SB_PAGEDOWN,0,NULL);
break;
case VK_UP:
OnVScroll(SB_LINEUP,0,NULL);
break;
case VK_DOWN:
OnVScroll(SB_LINEDOWN,0,NULL);
break;
case VK_LEFT:
OnHScroll(SB_LINEUP,0,NULL);
break;
case VK_RIGHT:
OnHScroll(SB_LINEDOWN,0,NULL);
break;
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CDrawView::OnChangeDlgEdit()
{
char p1[7];
CMainFrame* p_Wnd=(CMainFrame *)(AfxGetApp()->m_pMainWnd);
p_Wnd->m_wndDlgBar.GetDlgItemText(IDC_EDIT1,p1,6);
m_LineWide=(unsigned char)atoi(p1);
}
void CDrawView::OnChangeDlgCom()
{
CMainFrame* p_Wnd=(CMainFrame *)(AfxGetApp()->m_pMainWnd);
CComboBox* plist=(CComboBox*)(p_Wnd->m_wndDlgBar.GetDlgItem(IDC_COMBO1));
m_LineType=(unsigned char)plist->GetCurSel();
}
void CDrawView::OnBitmapCut()
{
CBitmap Bitmap;
CClientDC ht(this);
CDC MemDC;
RECT r1;
GetClientRect(&r1);
Bitmap.CreateCompatibleBitmap(&ht,r1.right-r1.left,r1.bottom-r1.top);
MemDC.CreateCompatibleDC(&ht);
MemDC.SelectObject(&Bitmap);
MemDC.BitBlt(0,0,r1.right-r1.left,r1.bottom-r1.top,&ht,0,0,SRCCOPY);
ht.BitBlt(0,0,r1.right-r1.left,r1.bottom-r1.top,&MemDC,100,100,SRCCOPY);
if(!OpenClipboard())
return;
EmptyClipboard();
::SetClipboardData(CF_BITMAP,Bitmap.m_hObject);
Bitmap.Detach();
CloseClipboard();
}
void CDrawView::OnBitmapPaste()
{
CClientDC ht(this);
CBitmap Bitmap;
BITMAP BitmapInfo;
HANDLE HBitmap;
CDC MemDC;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -