浅谈在应用CRectTracker类的程序中响应WM_LBUTTONUP消息

本文示例源代码或素材下载

  CRectTracker类也有人称之为“橡皮筋”类。我们可以通过Windows自带的画图板来了解这个类的作用:用“选定”功能在画图区随意选中一块儿区域,此时会出现一个由虚线和八个调整标记点组成的矩形选框,我们可通过鼠标点中矩形选框的中心移动其位置,并且能利用调整标记点来改变其大小……这个矩形选框其实就是一个“橡皮筋选框”。

  CRectTracker类的使用并不是什么新鲜的话题,然而在应用这个类的过程中,我却发现了一个小问题:我创建了一个对话框程序,希望利用CRectTracker类在对话框上画出一个“橡皮筋选框”,为了使鼠标按下并拖动鼠标的同时出现虚线的选择框,我在程序中加入了以下代码:

void CCRectTracker_DemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  //当鼠标左键按下时
  CRectTracker temp;
  temp.TrackRubberBand(this,point,TRUE);
  temp.m_rect.NormalizeRect();
  
  CDialog::OnLButtonDown(nFlags, point);
}

  这段代码确实实现了我所期望的效果。但在程序的另一个地方:

void CCRectTracker_DemoDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  //当鼠标左键松开时
  MessageBox(鼠标左键松开,松开,NULL);
  
  CDialog::OnLButtonUp(nFlags, point);
}

  OnLButtonUp()事件丝毫不理睬我鼠标的动作——MessageBox()并没有执行。仔细一想:TrackRubberBand()是以鼠标左键的松开作为结束标志的,当WM_LBUTTONUP消息发出后,TrackRubberBand()在OnLButtonUp()事件响应前就截获了该消息,所以OnLButtonUp()事件就无法正常响应了……想到这里,脑海中也就浮现了一个解决这个小问题的办法,那就是:在TrackRubberBand()后,向程序自身发送一个自己构造的WM_LBUTTONUP消息。于是将OnLButtonDown()中的代码改写成为以下形式:

void CCRectTracker_DemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  //当鼠标左键按下时
  CRectTracker temp;
  temp.TrackRubberBand(this,point,TRUE);
  temp.m_rect.NormalizeRect();
  //自己构造的WM_LBUTTONUP消息
  this->SendMessage(WM_LBUTTONUP,NULL,NULL);
  CDialog::OnLButtonDown(nFlags, point);
}

  测试后的结果另人满意,现在我所遇到的问题迎刃而解了。在本文附带的Demo程序中,程序分别获取鼠标左键按下和松开时的坐标,然后调用修改后的OnPaint()来画出“橡皮筋矩形”,下面给出Demo中的部分关键代码:

BOOL CCRectTracker_DemoDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
  // TODO: Add your message handler code here and/or call default
  //
  //改变光标的形状
  if (pWnd == this m_rectTracker.SetCursor(this, nHitTest))
    return TRUE;
  //
  else
    return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
void CCRectTracker_DemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  ///
  //如鼠标点击位置不在选框区域内,则构造一个新选框
  Invalidate(TRUE);
  if(m_rectTracker.HitTest(point)<0)
  {
    IsLButtonDown=TRUE;
    CRectTracker temp;
    temp.TrackRubberBand(this,point,TRUE);
    temp.m_rect.NormalizeRect();
    
    //鼠标(矩形选框)起始位置
    pt_start=point;
    //鼠标(矩形选框)结束位置
    GetCursorPos(pt_end);
    this->SendMessage(WM_LBUTTONUP,NULL,NULL);
  }
  //否则重置选框大小或位置
  else
  {
    m_rectTracker.Track(this,point,TRUE);
    m_rectTracker.m_rect.NormalizeRect();
    this->OnPaint();
  }
  ///
  
  CDialog::OnLButtonDown(nFlags, point);
}
void CCRectTracker_DemoDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  /
  //确保在构造一个新选框时才响应OnLButtonUp,否则在响应OnLButtonDblClk时会出现错误结果
  if(IsLButtonDown==TRUE)
  {
    //MessageBox(鼠标左键松开,松开,NULL);
    
    //由于GetCursorPos获得的pt_end是Screen坐标,故用ScreenToClient()进行转换
    rect.right=pt_end.x;
    rect.bottom=pt_end.y;
    ScreenToClient(rect);
    pt_end.x=rect.right;
    pt_end.y=rect.bottom;
    
    //left,top,right,bottom
    m_rectTracker.m_rect.SetRect(pt_start.x,pt_start.y,pt_end.x,pt_end.y);
    m_rectTracker.m_rect.NormalizeRect();
    
    this->OnPaint();
    IsLButtonDown=FALSE;
  }
  /
  
  CDialog::OnLButtonUp(nFlags, point);
}
void CCRectTracker_DemoDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  
  MessageBox(鼠标左键双击,双击,NULL);
  
  
  CDialog::OnLButtonDblClk(nFlags, point);
}

  由于本人水平所限,关于CRectTracker类的详细使用方法请参阅其他资料。谢谢!

 

http://www.techrss.cn/html/2008/09-27/116480.htm

转载于:https://www.cnblogs.com/wqj1212/archive/2009/04/03/1429207.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值