画点-画线-移动点(鼠标左键按下-鼠标右键按下-鼠标移动)
DrawGraphView.h typedef struct tagPoint //定义点结构
{
float x;
float y;
}PNT_INFO;
typedef struct tagLine //定义线结构
{
PNT_INFO pnt[100];
long num;
}LIN_INFO;
class CDrawGraphView : public CView
{
public:
short m_iDrawMode; //画图模式(初始:0; 画点:1; 画线:2; 移点:3)
long m_pointNum; //点数
long m_lineNum; //线数
long m_linepntNum; //一条线上的点数
int m_iNo; //移动点时,离鼠标最近距离点的点号(下标)
public:
PNT_INFO m_point[100]; //点数组:装点的个数
LIN_INFO m_line[100]; //线数组:装线的条数
PNT_INFO m_linepnt[100]; //线点数组:一条线上的点数 };
DrawGraphView.cpp #include //求距离中用到开平方运算
static long startx = 0; //起点:x
static long starty = 0; //起点:y
static long endx = 0; //终点:x
static long endy = 0; //终点:y
static short flagCap = 0; //标志:画线时记录鼠标捕获状态 static short flagMovePnt = 0; //标志:点移动
int CalcMinDist(PNT_INFO* pPnt,int num, PNT_INFO& pnt) //求所有点中,离鼠标点最近的点下标
{
float fTmp=0,fDist=99999;
int iNo = -1;
if(pPnt==NULL||num<=0)
return -1;
1
for(int i=0;iSelectObject(&pen);
pDC->SetROP2(R2_NOTXORPEN );
switch(m_iDrawMode) //绘图模式
{
case 1:
case 3: //画点和移动点
for(i=0;iRectangle((int)m_point[i].x-5,(int)m_point[i].y-5,(int)m_point[i].x+5,(int)m_point[i].
y+5);
break;
case 2: //画线
for(i=0;iMoveTo((int)m_line[i].pnt[j].x,(int)m_line[i].pnt[j].y);
pDC->LineTo((int)m_line[i].pnt[j+1].x,(int)m_line[i].pnt[j+1].y);
}
}
break;
default:
break;
}
}
2
void CDrawGraphView::OnDrawDrawpoint() //画点消息处理
{ // TODO: Add your command handler code here
m_iDrawMode = 1; //设置画点模式
}
void CDrawGraphView::OnDrawDrawline() //画线消息处理
{ // TODO: Add your command handler code here
m_iDrawMode = 2; //设置画线模式
}
void CDrawGraphView::OnDrawMovepoint() //移动点消息处理
{ // TODO: Add your command handler code here
m_iDrawMode = 3; //设置移动点模式
}
void CDrawGraphView::OnLButtonDown(UINT nFlags, CPoint point) //鼠标左键按下消息处理 {
// TODO: Add your message handler code here and/or call default
CDC* pDC = GetDC(); //获取设备环境
CPen pen, *pOldPen=NULL; //定义画笔
pDC->SetROP2(R2_NOTXORPEN ); //设置绘图模式(异或)
pOldPen = pDC->SelectObject(&pen); //将新画笔选入设备环境,并保存旧画笔
if(m_iDrawMode == 1) //如果画点
{
m_point[m_pointNum].x = (float)point.x; //将点的x坐标放入点数组
m_point[m_pointNum].y = (float)point.y; //将点的y坐标放入点数组
pDC->Rectangle((int)m_point[m_pointNum].x-5,(int)m_point[m_pointNum].y-5,(int)m_point[m_poi
ntNum].x+5,(int)m_point[m_pointNum].y+5); //在该点画小矩形
m_pointNum++; //点数增1
}
if(m_iDrawMode == 2) //如果画线
{
startx = point.x; //将鼠标点分别赋给起点和终点
starty = point.y;
endx = point.x;
endy = point.y;
pDC->MoveTo(startx,starty); //抬笔到起点
pDC->LineTo(endx,endy); //落笔到终点
m_linepnt[m_linepntNum].x = (float)point.x; //将鼠标点放入线数组
m_linepnt[m_linepntNum].y = (float)point.y;
m_linepntNum++; //线数组中的点数增1
SetCapture(); //设置有效区域的捕获方式
flagCap = 1; //抓线标志置1(0:第一个点; 1:非第一个点)
}
if(m_iDrawMode == 3) //如果是移动点
{
if(flagMovePnt==0)
3
{
flagMovePnt = 1; //移动点标志置1
PNT_INFO pnt;
pnt.x = (float)point.x; //将鼠标点放入点结构体变量
pnt.y = (float)point.y;
//需要加入求距离最短点的函数,返回点数组下标;
m_iNo = CalcMinDist(m_point,m_pointNum,pnt); //调函数求出离鼠标点最近点的下标
SetCapture(); //设置有效区域的捕获方式
}
else
{
flagMovePnt = 0;
::ReleaseCapture(); //释放捕获
}
}
pDC->SelectObject(pOldPen); //选回旧画笔
ReleaseDC(pDC); //释放设备环境
CView::OnLButtonDown(nFlags, point); }
void CDrawGraphView::OnRButtonDown(UINT nFlags, CPoint point) //鼠标右键按下消息处理 {
// TODO: Add your message handler code here and/or call default
CDC* pDC = GetDC(); //获取设备环境
CPen pen, *pOldPen=NULL; //定义画笔
pDC->SetROP2(R2_NOTXORPEN ); //设置绘图模式
pOldPen = pDC->SelectObject(&pen); //将画笔选入设备环境,并保存旧画笔
if(m_iDrawMode == 2) //如果画线
{
pDC->MoveTo(startx,starty); //抬笔到起点
pDC->LineTo(endx,endy); //落笔到终点
endx = point.x;
endy = point.y;
flagCap = 0;
for(int i=0;iSelectObject(pOldPen); //将旧画笔选入设备环境,为退出绘图作准备
ReleaseDC(pDC); //释放设备环境
CView::OnRButtonDown(nFlags, point); }
void CDrawGraphView::OnMouseMove(UINT nFlags, CPoint point) //鼠标移动消息处理 {
// TODO: Add your message handler code here and/or call default
CDC* pDC = GetDC(); //获取设备环境
CPen pen, *pOldPen=NULL; //定义画笔
pDC->SetROP2(R2_NOTXORPEN); //设置绘图模式
pOldPen = pDC->SelectObject(&pen); //将画笔选入设备环境,并保存旧画笔
if(m_iDrawMode == 2) //如果画线,进行橡皮筋方式画线
{
if(flagCap==1)
{
pDC->MoveTo(startx,starty); //擦除线(异或方式画)
pDC->LineTo(endx,endy);
endx = point.x; //记下新的点(鼠标点)
endy = point.y;
pDC->MoveTo(startx,starty); //画新线(从原始起点到鼠标点间画橡皮筋线)
pDC->LineTo(endx,endy);
}
}
if(m_iDrawMode == 3) //如果移动点
{
if(m_iNo<0) //点的下标异常处理
goto lab; //跳转到标号lab处
if(flagMovePnt==1)
{
//擦除离鼠标最近点的小矩形 pDC->Rectangle(m_point[m_iNo].x-5,m_point[m_iNo].y-5,m_point[m_iNo].x+5,m_point[m_iNo].y+5);
m_point[m_iNo].x = point.x; //将该点坐标写回到点数组中
m_point[m_iNo].y = point.y;
//在移动鼠标点画小矩形
pDC->Rectangle(m_point[m_iNo].x-5,m_point[m_iNo].y-5,m_point[m_iNo].x+5,m_point[m_iNo].y+5);
}
}
lab:
pDC->SelectObject(pOldPen); //将旧画笔选入设备环境,为退出绘图作准备
ReleaseDC(pDC); //释放设备环境
CView::OnMouseMove(nFlags, point);
}
5