CRectTracker(橡皮筋)类的使用

CRectTracker(俗称“橡皮筋”类)是一个非常有意思的类。你在Windows中,在桌面上用鼠标拖拽,便可以看到一个虚线的矩形框,它便是橡皮筋.它可以用做显示边界,你也可以扽它的八个角用来放大缩小,做框选使用。如何通过编程来实现这种功能呢?这就是CRectTracker类的作用;
介绍橡皮筋类前,先介绍其他两个类:

(1) Cpoint 类或Point类,cpoint.x   cpoint.y,作为屏幕上的坐标上的x和y 轴的坐标。

(2) CRect类,既矩形类。
crect.left   crect.bottom   crect.top   crect.right,
Crect::setrect(crect.left, crect.top, crect.right,crect.bottom);



CrectTracker 类成员:
一 数据成员:(摘自msdn 2000,省略了一些)
1. m_rect
当前橡皮筋矩形的矩形框的位置
2. m_sizeMin
决定橡皮筋矩形的最新的长和宽
3. m_nStyle
橡皮筋矩形的形式如:
CRectTracker::solidLine   用实线标记矩形框
CRectTracker::dottedLine 虚线
CRectTracker::hatchedBorder 影阴线
CRectTracker::resizeInside   改变大小的句柄在橡皮筋矩形框内部(点在橡皮筋矩形框
里面来改变大小)
CRectTracker::resizeOutside 改变大小的句柄在橡皮筋矩形框外部
CRectTracker::hatchInside 影阴线布满总个矩形框
二 成员函数:
1.void Draw( CDC* pDC ) const;
这个函数用来划矩形框的边框和内部区域。
2.void GetTrueRect( LPRECT lpTrueRect ) const;
这个函数用来换回矩形框的 矩形坐标,参数为CRECT类型,返回矩形
3.int HitTest( CPoint point ) const;
当你鼠标被按下的时候,你可以调用这个函数,它将返回鼠标点在了矩形框的什么位置:可以看出,返回值如果大于等于零则在四边形区域之内。如果小于则说明不在区域范围之内。

返回值代表的含义-1点在了四边形的外部0左上角1右上角2右下角3左下角(0,1,2,3顺时针转了一圈)4顶部5右部6底部7左部(还是顺时针转了一圈)8点在了四边形的内部,但没有击中前面的那八个点
4.BOOL SetCursor( CWnd* pWnd, UINT nHitTest ) const;
调用这个函数用来当鼠标放在矩形框时,显示各种鼠标形象

5.BOOL Track( CWnd* pWnd, CPoint point, BOOL bAllowInvert = FALSE, CWnd* pWndClipTo = NULL );
这个函数用来显示当人们用鼠标改变矩形框大小 或 拖拽矩形框时显示矩形框动作
一般由WM_LBUTTONDOWN 消息来触发这个函数, 不需要编写MouseMove函数,矩形框它就自动的变大小了呢?这就是Track()函数的功劳,从调用它到抬起鼠标键为止,它时刻的改变四边形的大小。

6.BOOL TrackRubberBand( CWnd* pWnd, CPoint point, BOOL bAllowInvert = TRUE );
当鼠标在空区域拖拽时显示橡皮筋矩形框,让鼠标画一个 橡皮筋 区域,第一个参数,画“橡皮筋”的窗体的指针,当然是this ,第二个参数,画“橡皮筋”的起始点。 让我们注意第三个参数,它非常有意思。当你使用 FALSE时(TRUE 值是缺省的),你的“橡皮筋”只能从左上到右下的画,不允许反向。编译运行一下FALSE这个值。
特别值得注意的是:在 TrackRubberBand的过程中是以右键的抬起为结束的,这其间并没有 CViewMouseMove发生。这一点一定要记住!这时鼠标画过的区域已经记录在CrectTracker 类数据成员 m_rect里面了,即CrectTracker:: m_rect.
下面我举一个自己已经测试的例子:
我要实现的是一个在图片控件上选定一部分的功能。首先,在界面上画一个图片控件, ID为: IDC_PICTURE,实现在控件里选定某一块内容的功能,
首先,在重载主界面的 OnLButtonDown(鼠标左键点下消息)函数

CRectTracker m_tracker;

m_tracker.m_nStyle=CRectTracker::resizeInside|CRectTracker::solidLine|CRectTracker::hitNothing;


void CmrDlg::OnLButtonDown(UINT nFlags, CPoint point)   //在鼠标左键消息中响应拖拽
{
       // TODO: 在此添加消息处理程序代码和 /或调用默认值
       int nIn;                         //定义一个鼠标的点击值;
       nIn=m_tracker.HitTest(point);       //看看点到了哪了

       CRect Prect1;          //定义图片的矩形
       CRect Trect;          //定义橡皮筋框的矩形
       CRect Prect;         //图片矩形框

       GetDlgItem(IDC_PICTURE)->GetWindowRect(&Prect1);    //得到图片的矩 //形大小

       ScreenToClient(&Prect1);   //将图片框的绝对矩形大小

//判断是否在图片框内,不处理不在图片框内的点击
              if (point.x<Prect1.left||point.x>Prect1.right||point.y<Prect1.top||point.y>Prect1.bottom)
                               return;

m_tracker.SetCursor(this,nFlags); //改变鼠标的形状
       if(nIn<0)                 //不在四边形区域内;
       {
              Invalidate(true);
              m_tracker.TrackRubberBand(this,point,false);   //不在矩形框内则画橡皮 ///筋框


              GetDlgItem(IDC_PICTURE)->GetWindowRect(&Prect); //得到图片框的 //矩形
              ScreenToClient(&Prect);
              Trect=m_tracker.m_rect;   //得到画好的橡皮筋框

              //调整大小
              Trect.top=(Trect.top<Prect.top?Prect.top:Trect.top);
              Trect.left=(Trect.left<Prect.left?Prect.left:Trect.left);
              Trect.bottom=(Trect.bottom>Prect.bottom?Prect.bottom:Trect.bottom);
              Trect.right=(Trect.right>Prect.right?Prect.right:Trect.right);

              m_tracker.m_rect.SetRect(Trect.left,Trect.top,Trect.right,Trect.bottom); //画出调整好的矩形框

              CClientDC dc(this);
              m_tracker.Draw(&dc);    //画好矩形框

       }
       else
              //在四边形区域内:
       {
              Invalidate(); //重画界面

              CClientDC dc(this);
              GetDlgItem(IDC_PICTURE)->GetWindowRect(&Prect);


           ClipCursor(&Prect); //api函数,将鼠标限制在图片框内

              m_tracker.Draw(&dc);
              m_tracker.Track(this,point,false);

            ScreenToClient(&Prect);

              Trect=m_tracker.m_rect;   //得到画好的橡皮筋框

//调整矩形框的位置
              if (Trect.top<Prect.top)
              {//超出图片框顶部的位置
                     Trect.bottom=Prect.top-Trect.top+Trect.bottom;
                     Trect.top=Prect.top;
              }
              if (Trect.bottom>Prect.bottom)
              {//超出底部的位置
                     Trect.top=Prect.bottom-Trect.bottom+Trect.top;
                     Trect.bottom=Prect.bottom;
              }
              if (Trect.right>Prect.right)
              {//超出右边
                     Trect.left=Prect.right-Trect.right+Trect.left;
                     Trect.right=Prect.right;
              }
              if (Trect.left<Prect.left)
              {//超出左边
                     Trect.right=Prect.left-Trect.left+Trect.right;
                     Trect.left=Prect.left;
              }
//设置矩形框大小
              m_tracker.m_rect.SetRect(Trect.left,Trect.top,Trect.right,Trect.bottom);

              m_tracker.Draw(&dc);
              // Track()CRectTracker中最富魅力的函数。它时时的改变调用者的 m_rect;
              ClipCursor(NULL);   //释放对鼠标的限制
       }

       AbsRect.left=abs(Trect.left-Prect.left);
       AbsRect.right=abs(Trect.right-Prect.right);
AbsRect.top=abs(Trect.top-Prect.top);
AbsRect.bottom=abs(Trect.bottom-Prect.bottom);

       CDialog::OnLButtonDown(nFlags, point);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值