开发文章

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);
}

感谢 米大鸢 支持 磐实编程网 原文地址:
blog.csdn.net/u012372584/article/details/54645756

文章信息

发布时间:2017-01-21

作者:米大鸢

发布者:aquwcw

浏览次数: