用鼠标拖动图片移动

来源:互联网 发布:美丽水世界优化补丁 编辑:程序博客网 时间:2024/04/29 07:57

 

 

拖动图片要响应3个鼠标消息

OnLButtonDown,OnLButtonUp,OnMouseMove

 

左键按下时:

                         要判断是否在图像内部按下的,若是捕获图片

 

左键释放时:

                         释放图片

鼠标移动时: 根据鼠标移动,实时重绘图片

 

为此,设三个类变量:

CPoint pt;//  保存图片起始坐标

BOOL bcapture; //图片是否捕获

CSize offsetsize;  //鼠标与图片起始点的偏移量

 

首先是初始化:

 

CMovePictureView::CMovePictureView(){// TODO: add construction code herebcapture=FALSE;pt.x=0;pt.y=0;offsetsize.cx=0;offsetsize.cy=0;}

 

然后是响应OnLButtonDown消息

void CMovePictureView::OnLButtonDown(UINT nFlags, CPoint point) {CRect selrc(pt,size);CClientDC dc(this);OnPrepareDC(&dc);CRgn rgn;rgn.CreateRectRgnIndirect(&selrc);if(rgn.PtInRegion(point)){SetCapture();bcapture=TRUE;CPoint rcpt(pt);offsetsize=point-rcpt;SetCursor(LoadCursor(NULL,IDC_CROSS));}CScrollView::OnLButtonDown(nFlags, point);}


响应UP消息

void CMovePictureView::OnLButtonUp(UINT nFlags, CPoint point) {ReleaseCapture();bcapture=FALSE;CScrollView::OnLButtonUp(nFlags, point);}


响应Move消息

void CMovePictureView::OnMouseMove(UINT nFlags, CPoint point) {if(bcapture){CClientDC dc(this);OnPrepareDC(&dc);CRect oldrc(pt,size);InvalidateRect(oldrc,TRUE);pt=point-offsetsize;CRect newrc(pt,size);InvalidateRect(newrc,TRUE);}CScrollView::OnMouseMove(nFlags, point);}


 

       如果你是在整个视图中画图或整个对话框中画图,这样就可以实现图片的平移了。但是,如果你是在对话框中的CStatic 图片控件中画图的话,就会出现问题。

       其原因在于:响应鼠标消息时,CPoint 点的坐标是对话框客户区的坐标(因为响应的是对话框的鼠标消息,所以坐标系是对话框坐标系),而我们的图是用的CSTATIC图片控件的坐标系,两个坐标系不同,所以发生了混淆,导致,不能实现我们想要的结果。

解决方法:  响应鼠标消息时,以屏幕坐标为中间媒介。具体如下: 先将CPoint 由对话框坐标系转换为屏幕坐标系,然后再将屏幕坐标系转换为控件坐标系

 

void CShowImageDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CPoint orgPoint=point;         this->ClientToScreen(&point);  //对话框坐标系转换为屏幕坐标系 m_image.ScreenToClient(&point); // 屏幕坐标系转换为控件坐标系CRect selRc(m_pt,m_size); //控件坐标CRgn rgn;rgn.CreateRectRgnIndirect(&selRc);if (rgn.PtInRegion(point)) // 在控件坐标系中判断,所以应先将point转换为控件坐标{SetCapture();m_bcapture=TRUE;CPoint rcpt(m_pt);m_offsetsize=point-rcpt;SetCursor(LoadCursor(NULL,IDC_CROSS));}CDialog::OnLButtonDown(nFlags, orgPoint);}


 

 

void CShowImageDlg::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值ReleaseCapture();m_bcapture=FALSE;CDialog::OnLButtonUp(nFlags, point);}


 

void CShowImageDlg::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CPoint orgPoint=point;this->ClientToScreen(&point);m_image.ScreenToClient(&point);if (m_bcapture){CRect oldRc(m_pt,m_size);  //控件中坐标     m_image.ClientToScreen(&oldRc);// 转换为屏幕坐标this->ScreenToClient(&oldRc);  // 转换为对话框坐标,然后才能正确的调用 InvalidateRect(oldRc,TRUE);因为,此函数是在对话框中调用的,所以其坐标是对话框坐标InvalidateRect(oldRc,TRUE);m_pt=point-m_offsetsize;CRect newRc(m_pt,m_size);m_image.ClientToScreen(&newRc);  //同样,也要将控件坐标newRc转换成对话框坐标,转换后,方可正确的调用InvalidateRect函数this->ScreenToClient(&newRc);InvalidateRect(newRc,TRUE);}CDialog::OnMouseMove(nFlags, orgPoint);}


 

 

 

感谢某网友,提供了初始的源程序
原创粉丝点击