MFC两种拖动鼠标动态画图的方法

原创 2015年07月09日 20:42:38

一般来说,一次画图的过程分为鼠标左键按下,鼠标移动,鼠标左键弹起。要想在鼠标移动的过程中动态显示所画的图的变化过程,所画的图只能是可以由两个点确定的图形,如直线、矩形、椭圆等等。举例来说,如何画一条线段?我们要知道起点和终点。起点自然是鼠标左键按下时鼠标的位置,终点是鼠标移动时当前的鼠标位置。既然是拖动鼠标动态画图,那么画图的动作自然是在鼠标移动的响应函数OnMouseMove()里完成。要想让图跟着鼠标移动而变化,就必须在鼠标移动时不断根据鼠标新位置画图,然而不停画图,原来画的旧图还停留在那里。本来一次鼠标移动只要画一根线段,现在一次鼠标移动画出好多根线段。所以关键是如何擦除旧图。第一种方法是保存上一次鼠标停留的位置,然后用背景色的画笔把旧图描一遍。

//鼠标左键按下

void C画图Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
  mousemode = 1;//标识鼠标左键已按下
  pt_Begin = pt_End = pt_Mid = point;//pt_Begin标识起点,pt_End标识新终点,pt_Mid标识旧终点
 CDialogEx::OnLButtonDown(nFlags, point);
}

//鼠标移动

void C画图Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if (mousemode == 1)//确保鼠标移动是在鼠标左键按下后
 {
  pt_Mid = pt_End;//将原终点的值赋给pt_Mid
  pt_End = point;//将当前鼠标的位置赋给新终点
  EraseLine(pt_Begin, pt_Mid);//擦掉旧线段
  DrawLine(color,pt_Begin, pt_End);//画新线段

CDialogEx::OnMouseMove(nFlags, point);
  }
 }

但是这样会把原来作好的图也擦掉。想到的解决方法是将原来作好的图的数据(如起点和终点,还可以扩充如画笔颜色,图形种类等,写成一个class)储存在vector里面,擦掉旧图后先把储存在vector里面的图画一遍,再画新图,当然也可以画新图之后再把储存在vector里面的图画一遍。储存画好的图在鼠标左键弹起的时候进行。

//鼠标移动

void C画图Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if (mousemode == 1)//确保鼠标移动是在鼠标左键按下后
 {
  pt_Mid = pt_End;
  pt_End = point;
  EraseLine(pt_Begin, pt_Mid);//擦掉旧线段
  DrawLine(color,pt_Begin, pt_End);//画新线段
  DrawpGraph(vec_pGraph);//重画已画好的图形

CDialogEx::OnMouseMove(nFlags, point);
 }

//鼠标左键弹起

void C画图Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if (mousemode == 1)
 {
  mousemode = 0;
  vector<POINT> vec;
  vec.push_back(pt_Begin);
  vec.push_back(pt_End);
  previousGraph temp(drawmode, color, vec);//previousGraph是储存每个画好的图的数据的class
  vec_pGraph.push_back(temp);//将这次画的图形的种类,颜色,起点和终点存入向量vec_pGraph中
  pt_Begin = { 0, 0 };
  pt_Mid = { 0, 0 };
  pt_End = { 0, 0 };
 }

CDialogEx::OnLButtonUp(nFlags, point);

}

将画好的图的数据储存在vector里面的一个好处是我们可以很容易地进行撤销与重做。然而假如一开始不是在一张空白的图上作画,而是在一张背景图上作画时,这样还是会擦掉背景图。第二种方法可以解决这个问题。

第二种方法进行动态画图的思路是鼠标左键按下时将当前窗口的内容保存为一张图片,鼠标移动过程中每次画新图之前都先载入这张图片。

void CDrawXView::DrawpGraph()//函数,功能是载入保存了鼠标左键按下时窗口图像的图片
{
 test.Attach(image.Detach());//test是CBitmap类型的对象
 CDC MemDC;
 CDC dc;
 MemDC.CreateCompatibleDC(NULL);
 dc.CreateCompatibleDC(&MemDC);
 dc.SelectObject(&test);
 CClientDC ClientDC(this);
 ClientDC.BitBlt(0, 0, //目标设备逻辑横、纵坐标
  AreaWidth, AreaHeight, //显示位图的像素宽、高度
  &dc, //待显示位图数据的设备情境对象
  0, 0, //源数据中的横、纵坐标
  SRCCOPY);
}

//鼠标左键按下
void CDrawXView::OnLButtonDown(UINT nFlags, CPoint point)
{
 mousemode = 1;
 CRect rect; GetClientRect(&rect);//获取画布大小  
 CClientDC dc(this); 
 hbit = CreateCompatibleBitmap(dc, rect.right - rect.left, rect.bottom - rect.top);//创建兼容位图
 HDC hdc = CreateCompatibleDC(dc);      //创建兼容DC,以便将图像保存为不同的格式 
 HBITMAP hOldMap = (HBITMAP)SelectObject(hdc, hbit); //将位图选入DC,并保存返回值  
 BitBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, dc, 0, 0, SRCCOPY); //将屏幕DC的图像复制到内存DC中    
 hbit = (HBITMAP)SelectObject(hdc, hOldMap); 
 image.Attach(hbit);//将图像保存到image中,image是CImage类型
 pt_Begin = pt_End = pt_Mid = point;
 CScrollView::OnLButtonDown(nFlags, point);
}
//鼠标移动
void CDrawXView::OnMouseMove(UINT nFlags, CPoint point)
{
 if (mousemode == 1)
 {
  pt_End = point;
  DrawpGraph();
  DrawLine(color, pt_Begin, pt_End);
 }
 CScrollView::OnMouseMove(nFlags, point);
}

//鼠标左键弹起

void C画图Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if (mousemode == 1)
 {
  mousemode = 0;
  pt_Begin = { 0, 0 };
  pt_End = { 0, 0 };
 }

CDialogEx::OnLButtonUp(nFlags, point);

}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

MFC picture控件画矩形框选取图像ROI区域

参考《关于对话框picture控件里画矩形的问题》http://bbs.csdn.net/topics/390772898 上述帖子中提到了两种方法,一是#5提到的直接在鼠标响应函数中画矩形框,二是使...

VC鼠标拖动动态画矩形框

要实现的功能实际上很简单,一般人都用到见惯不惯了,但是实现起来还是有点意思的。 问题详细描述:(三步) 单击鼠标左键时记录下单击点; 鼠标拖动时,显示的矩形框能够动态的跟随显示; 释放鼠标左键...

问题日记:VC MFC 鼠标移动画矩形

昨天的时候,模仿人家的软件已经七七八八啦,开始不断完善的工作。首先是完善用鼠标拖动矩形选择东西,开始当然进入死胡同,在OnMouseMove里单纯画矩形,结果测试移动一下鼠标杯了,n个矩形刺瞎了我的眼...

【计算机图形学课程】二.MFC鼠标响应函数模拟画图软件

上一篇文章我们讲述MFC绘制图形的基本函数,包括绘制直线、绘制矩形、绘制椭圆及绘制文字,同时通过绕圆旋转和矩形平移简单的理解了图形学知识。这篇文章我将介绍鼠标响应和键盘响应,通过这些事件让学生实现一个...

mfc 图片拖拽效果

拖动是界面编程频繁使用的一个效果,在windows系统下可谓大行其道。纵观时下的应用软件几乎各个都支持各种各样拖动的效果,windows7更是把拖动做到了极致。其实说起来拖动的实现也很简单,对于有句柄...

MFC 实现图片的拖拽功能,代码很详细,贴过去就能用!

拖动是界面编程频繁使用的一个效果,在windows系统下可谓大行其道。纵观时下的应用软件几乎各个都支持各种各样拖动的效果,windows7更是把拖动做到了极致。其实说起来拖动的实现也很简单,对于有句柄...

拖动效果的一个实现方案

本文介绍了通过CImageList实现拖动的方法

MFC 鼠标画线总结

使用mfc鼠标画线,主要使用鼠标左键单击,鼠标移动,鼠标右键单击等响应函数完成。      在mfc画线是主要要注意以下几点:         1、坐标系问题:在鼠标左键单击的响应函数中获取的鼠标...

怎样使用MFC单文档程序编写一个鼠标画线程序

在visual C++6.0里面 文件->新建->工程里面的MFC Appwizard [EXE] 除了第二步选单文档,基本上都是默认的。 建一个文件进行一下操作 我...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)