MFC 鼠标移动画矩形

 

MFC 鼠标移动画矩形

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

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

我相信人家做得到的,我也做得到,只是我还不知道而已。于是上网找资料,虽说网上有很多资料,可也有点费时,有时看了资料测试还不一定行,汗,不行你放上网干嘛啦。最后结果OK啦:

现写下来:

(1 )在类里定义变量和消息:

bool m_bClickEmpty; //判断是否点击了空白的地方,以实现拖动框选择 

CPoint OldEmptyBegin;//点击空白开始的座标

CPoint NowEmptyEnd;//移动时保存座标

afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

( 2 )在鼠标相关的消息里面写代码:

void XX::OnLButtonDown(UINT nFlags, CPoint point){

       m_bClickEmpty = true;

      OldEmptyBegin = point;

       NowEmptyEnd = point;

}

void XX::OnMouseMove(UINT nFlags, CPoint point)

{

     if ( m_bClickEmpty )     {          CClientDC dc(this);

          CBrush *pBrush = CBrush::FromHandle( (HBRUSH)GetStockObject( NULL_BRUSH) );

          CBrush *POldBrush = dc.SelectObject( pBrush );

          int nOldMode = dc.SetROP2(R2_NOTXORPEN);

          dc.Rectangle( &CRect( OldEmptyBegin, NowEmptyEnd ) );

          dc.Rectangle( &CRect( OldEmptyBegin, point ) );

          NowEmptyEnd = point;

         dc.SelectObject( POldBrush );

         dc.SetROP2( nOldMode );

    }

}

void XX::OnLButtonUp(UINT nFlags, CPoint point){

      if ( m_bClickEmpty )      {           m_bClickEmpty = false;

           CClientDC dc(this);

           CBrush *pBrush = CBrush::FromHandle( (HBRUSH)GetStockObject( NULL_BRUSH) );

           CBrush *POldBrush = dc.SelectObject( pBrush );

           int nOldMode = dc.SetROP2(R2_NOTXORPEN);

          dc.Rectangle( &CRect( OldEmptyBegin, NowEmptyEnd ) );

          dc.SelectObject( POldBrush );

         dc.SetROP2( nOldMode );

      }}

 

有时候最好还是让鼠标限制在一个的主框里面这样会比较好办(座标,鼠标不用走到外面,在外面也没用),用ClipCursor.





-----------------------------+_+------------------2013-05-28

上面都是老方法了,叫橡皮筋技术,但是在不停拖动过程中还是会出现一些难看的重绘,应该用双缓冲,保存鼠标点击下去时候的点StartPoint,和鼠标移动时候的点EndPoint,直接刷新界面。这样更好.

 

  1. CPoint m_StartPoint;//开始点  
  2.   
  3. CPoint m_EndPoint;//结束点   
  4.   
  5. BOOL m_bLBDown;//鼠标是否按下  
CPoint m_StartPoint;//开始点

CPoint m_EndPoint;//结束点

BOOL m_bLBDown;//鼠标是否按下

  1. afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  
  2. afx_msg void OnLButtonUp(UINT nFlags, CPoint point);  
  3. afx_msg void OnMouseMove(UINT nFlags, CPoint point);  
  4. afx_msg BOOL OnEraseBkgnd(CDC* pDC);  
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);

  1. m_bLBDown = FALSE;//在构造函数初始化为FALSE  
m_bLBDown = FALSE;//在构造函数初始化为FALSE

  1. void CMy22Dlg::OnPaint()  
  2. {  
  3.     CPaintDC dc(this);  
  4.   
  5.     //绘制背景   
  6.     CRect rect;  
  7.     GetClientRect(&rect);  
  8.   
  9.     CBrush bruDB(RGB(255, 255, 255));//背景颜色  
  10.   
  11.     dc.FillRect(&rect, &bruDB);  
  12.   
  13.     //绘制拖动矩形   
  14.     if (m_bLBDown)  
  15.     {  
  16.         CRect rect(m_StartPoint, m_EndPoint);  
  17.   
  18.         rect.NormalizeRect();//规范化矩形   
  19.   
  20.         CBrush bruPen(RGB(255, 0, 0));//矩形边框颜色  
  21.   
  22.         dc.FrameRect(&rect, &bruPen);  
  23.     }  
  24. }  
  25.   
  26. void CMy22Dlg::OnLButtonDown(UINT nFlags, CPoint point)  
  27. {  
  28.     m_StartPoint = point;  
  29.   
  30.     m_EndPoint = point;  
  31.   
  32.     m_bLBDown = TRUE;  
  33.   
  34.     SetCapture();//设置鼠标捕获   
  35.   
  36.     CDialogEx::OnLButtonDown(nFlags, point);  
  37. }  
  38.   
  39.   
  40. void CMy22Dlg::OnLButtonUp(UINT nFlags, CPoint point)  
  41. {  
  42.     if(this == GetCapture())  
  43.     {  
  44.         ReleaseCapture();  
  45.     }  
  46.   
  47.     m_bLBDown = FALSE;  
  48.   
  49.     Invalidate(FALSE);//更新界面   
  50.   
  51.     CDialogEx::OnLButtonUp(nFlags, point);  
  52. }  
  53.   
  54.   
  55. void CMy22Dlg::OnMouseMove(UINT nFlags, CPoint point)  
  56. {  
  57.     if (m_bLBDown)  
  58.     {  
  59.         m_EndPoint = point;  
  60.   
  61.         Invalidate(FALSE);//更新界面  
  62.     }  
  63.   
  64.     CDialogEx::OnMouseMove(nFlags, point);  
  65. }  
  66.   
  67.   
  68. BOOL CMy22Dlg::OnEraseBkgnd(CDC* pDC)  
  69. {  
  70.     //return CDialogEx::OnEraseBkgnd(pDC);不需要重绘背景  
  71.     return TRUE;  
  72. }  
void CMy22Dlg::OnPaint()
{
	CPaintDC dc(this);

	//绘制背景
	CRect rect;
	GetClientRect(&rect);

	CBrush bruDB(RGB(255, 255, 255));//背景颜色

	dc.FillRect(&rect, &bruDB);

	//绘制拖动矩形
	if (m_bLBDown)
	{
		CRect rect(m_StartPoint, m_EndPoint);

		rect.NormalizeRect();//规范化矩形

		CBrush bruPen(RGB(255, 0, 0));//矩形边框颜色

		dc.FrameRect(&rect, &bruPen);
	}
}

void CMy22Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_StartPoint = point;

	m_EndPoint = point;

	m_bLBDown = TRUE;

	SetCapture();//设置鼠标捕获

	CDialogEx::OnLButtonDown(nFlags, point);
}


void CMy22Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
	if(this == GetCapture())
	{
		ReleaseCapture();
	}

	m_bLBDown = FALSE;

	Invalidate(FALSE);//更新界面

	CDialogEx::OnLButtonUp(nFlags, point);
}


void CMy22Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
	if (m_bLBDown)
	{
		m_EndPoint = point;

		Invalidate(FALSE);//更新界面
	}

	CDialogEx::OnMouseMove(nFlags, point);
}


BOOL CMy22Dlg::OnEraseBkgnd(CDC* pDC)
{
	//return CDialogEx::OnEraseBkgnd(pDC);不需要重绘背景
	return TRUE;
}


更多 0
-
查看评论
3楼 wangjian88552012-10-24 17:12发表 [回复] [引用][举报]
你好 ,用的你方法绘制矩形,最后矩形怎么消失了呢
Re: cvbtvbwu2013-03-24 09:45发表 [回复] [引用][举报]
MFC中实现鼠标左键选中矩形移动,可以按照以下步骤实现: 1. 定义一个CRect对象,用于表示选中的矩形。 2. 在鼠标左键按下的消息响应函数中,根据鼠标的位置确定选中的矩形,并将其保存到CRect对象中。 3. 在鼠标移动的消息响应函数中,判断是否已经选中了矩形。如果已经选中了矩形,则根据鼠标移动的偏移量,更新选中矩形的位置。 4. 在鼠标左键抬起的消息响应函数中,清除选中矩形的标记。 下面是一个示例代码: ``` CRect selectedRect; // 保存选中的矩形 // 鼠标左键按下 void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { // 判断是否选中了矩形 if (m_rect.PtInRect(point)) { selectedRect = m_rect; // 保存选中的矩形 } } // 鼠标移动 void CMyView::OnMouseMove(UINT nFlags, CPoint point) { // 判断是否已经选中了矩形 if (!selectedRect.IsRectEmpty()) { // 计算鼠标移动的偏移量 int offsetX = point.x - m_lastMousePos.x; int offsetY = point.y - m_lastMousePos.y; // 更新选中矩形的位置 selectedRect.OffsetRect(offsetX, offsetY); // 重绘图形 Invalidate(); } // 保存上一次鼠标的位置 m_lastMousePos = point; } // 鼠标左键抬起 void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { selectedRect.SetRectEmpty(); // 清除选中矩形的标记 } ``` 需要注意的是,在鼠标移动的消息响应函数中,需要调用Invalidate函数来触发重绘操作。同时,为了计算鼠标移动的偏移量,需要保存上一次鼠标的位置。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值