CRectTracker(橡皮筋)

来源:互联网 发布:琢本网络 编辑:程序博客网 时间:2024/04/28 13:12
 
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);
}

原创粉丝点击