分享
 
 
 

CRectTracker类的使用

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

CRectTracker类的使用

作者:二鸡蛋

CRectTracker(俗称“橡皮筋”类)是一个非常有意思的类。你在Windows中经常看到这样的情况:它可以用做显示边界,你也可以扽它的八个角用来放大缩小,或做框选使用。如何通过编程来实现这种功能呢?这就是CRectTracker类的作用;

(框选) (显示边界并可以缩放)

例子(源程序)

你打开上面的那个工程文件,编译运行一下。你将看到CRectTracker的几种功能;

下面让我们来从头做一个新的工程文件,来慢慢掌握它的功能吧。

建立一个单文档的工程文件,将其命名为Rect。单击finish完成工程的建立;先编译一下,来第一次生成obj文件吧,在它生成的过程中,我们继续往下讲解;

第一步:

在CRectDoc类中生成一个公有的数据成员:m_rectTracker;之所以设成公有,因为要在View中调用它。接着我们来初始化它,在CRectDoc::CrectDoc构造函数中:

CRectDoc::CRectDoc()

{ // TODO: add one-time construction code here

m_rectTracker.m_rect.SetRect(0,0,100,100);

m_rectTracker.m_nStyle=CRectTracker::resizeInside|CRectTracker::dottedLine;

}

其中: m_rect是CRectTracker中用来控制四边形的大小位置的数据成员, SetRect使用的是View的坐标; m_nStyle是CRectTracker的类型,其中:CRectTracker::resizeInside和CRectTracker::resizeOutside是说明在m_rect的内部还是外部画区域(它们是互异的),CrectTrakcer::dottedLine是用点划线来画四边形的区域边界。 其他的值还有: CRectTracker::solidLine:用来画实线边界;(和dottedLine是互异的) CRectTracker::hatchedBorder:边界带抛面线; CRectTracker::hatchInside:内部带抛面线; 你可以运行前面的例子,上述参数都有使用。你也可以在第二步中逐一使用它们来加深理解它们各自的含义;

第二步:

接着我门在视图中画一个蓝色的椭圆; 在CRectView的OnDraw中继续我们的工作:

void CRectView::OnDraw(CDC* pDC)

{

CRectDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

CBrush brush(RGB(0,0,255));//生成蓝色的画刷;

CBrush *oldBrush=pDC->SelectObject(&brush);//将画刷选进dc;

CRect rect;

//GetTrueRect(&rect)得到CRectTracker中的m_rect的大小,将其传递给rect;

pDoc->m_rectTracker.GetTrueRect(&rect);

pDC->Ellipse (rect);//画椭圆;

//Draw tracking rectangle.

pDoc->m_rectTracker.Draw(pDC);//这句画才真正的将这个四边形画出来;

//Select blue brush out of device context.

pDC->SelectObject (oldBrush);//恢复原来的画刷;

}

注释已经在程序里了,不用再多说,编译一下。一个椭圆外带四边形边界(点划线),且四边形的四周有八个黑点;这就是CRectTracker.,你现在可以改变一下m_nStyle试试看各参数的含义;

第三步:如何象例子中的那样随着鼠标的移动自动在椭圆的周围改变光标呢?很简单只要将下面的代码加入到CRectView::OnSetCursor()就可以了:它调用了CRectTracker中的SetCursor()函数:

BOOL CRectView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)

{ // TODO: Add your message handler code here and/or call default

CRectDoc* pDoc = GetDocument();

if (pWnd == this && pDoc->m_rectTracker.SetCursor(this, nHitTest))

return TRUE;

return CView::OnSetCursor(pWnd, nHitTest, message);

}

编译运行一下,鼠标变化了。 第四步:我们再做另一个用于鼠标的CRectTracker类。它的作用是在鼠标按下以后可以显示虚线的选择框: 先让我们看看效果:

在CRectView中的加入如下代码:

void CRectView::OnLButtonDown(UINT nFlags, CPoint point)

{

CRectTracker temp;

temp.TrackRubberBand(this,point,TRUE);

temp.m_rect.NormalizeRect();//正规化;

CView::OnLButtonDown(nFlags, point);

}

编译运行,当你按下鼠标并拖动,你将看到效果了。

我们如何让鼠标画一个“橡皮筋”区域呢? 在CRectTracker类中的成员函数就是:TrackRubberBand(this,point,TRUE); 注意其中的三个参数:

第一个参数,画“橡皮筋”的窗体的指针,当然是this

第二个参数,画“橡皮筋”的起始点。

让我们注意第三个参数,它非常有意思。当你使用FALSE时(TRUE 值是缺省的),你的“橡皮筋”只能从左上到右下的画,不允许反向。编译运行一下FALSE这个值。

特别值得注意的是:在TrackRubberBand的过程中是以右键的抬起为结束的,这其间并没有CView的MouseMove发生。这一点一定要记住!这时鼠标画过的区域已经记录在temp的m_rect 中了,你可以根据它进行后续的判断工作。至于下面的正规化语句函数的作用与CRect中的正规化函数的作用一致:使四边形的四个角的坐标符合右大于左,底大于顶的坐标值。它主要是为了防止你使用TrackRubberBand 的FALSE参数而引起的可能出现的错误。

第五步:

让我们回到那个蓝色的椭圆,在开始新的步骤之前,首先来介绍一下HitTest(CPoint point)的功能:当你鼠标被按下的时候,你可以调用这个函数,它将返回鼠标点在了四边形的什么位置:

返回值

代表的含义

-1

点在了四边形的外部

0

左上角

1

右上角

2

右下角

3

左下角(0,1,2,3顺时针转了一圈)

4

顶部

5

右部

6

底部

7

左部(还是顺时针转了一圈)

8

点在了四边形的内部,但没有击中前面的那八个点

可以看出,返回值如果大于等于零则在四边形区域之内。如果小于则说明不在区域范围之内。因此我们需要加一个公有的成员函数:BOOL bDraw;为了方便起见,我把它加到CRectView中,(你也许会说,为什么不加到doc中,我也知道这有勃编程的原理,反正我高兴就得,都说C++给人了很大的自由度,所以你也别限制我)。先把它初始化为FALSE,表示不画边界,当TRUE时,表示要画边界。 定义: class CRectView : public CView

{

…………

public:

BOOL bDraw;

…….

}

初始化:

CRectView::CRectView()

{

// TODO: add construction code here

bDraw=FALSE;

}

将OnDraw改一下,加一句话:

void CRectView::OnDraw(CDC* pDC)

{

CRectDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

CBrush brush(RGB(0,0,255));//生成蓝色的画刷;

CBrush *oldBrush=pDC->SelectObject(&brush);//将画刷选进dc;

CRect rect;

pDoc->m_rectTracker.GetTrueRect (&rect);

//GetTrueRect(&rect)可以得到CRectTracker中的m_rect的大小,将其传递给rect;

if(bDraw) //*************新加的语句***************

pDC->Ellipse (rect);//画椭圆;

//Draw tracking rectangle.

pDoc->m_rectTracker.Draw (pDC);//***这句画才真正的将这个四边形画出来;***

//Select blue brush out of device context.

pDC->SelectObject (oldBrush);//恢复原来的画刷;

}

编译运行一下,椭圆的边界没有了。

好了,预备知识讲完了,让我们来完成这个程序吧:

void CRectView::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

int nIn; //定义一个鼠标的点击值;

nIn=GetDocument()->m_rectTracker.HitTest(point); //看看点到了哪了

if(nIn<0) //不在四边形区域内;

{

CRectTracker temp;

temp.TrackRubberBand(this,point,TRUE);

temp.m_rect.NormalizeRect();

CRectTracker interRect;

//在建立一个CRectTracker;用于记录鼠标与椭圆的交集。

if(interRect.m_rect.IntersectRect(temp.m_rect,GetDocument()->m_rectTracker.m_rect))

bDraw=TRUE; //如果有交集,则画四边形的边界,说明选择了椭圆

else bDraw=FALSE;

Invalidate(); //引起OnDraw函数的发生;

}

else

//在四边形区域内:

{

CClientDC dc(this);

GetDocument()->m_rectTracker.Draw(&dc);

GetDocument()->m_rectTracker.Track(this,point,TRUE);

// Track()是CRectTracker中最富魅力的函数。它时时的改变调用者的m_rect;

bDraw=TRUE;

Invalidate();

}

CView::OnLButtonDown(nFlags, point);

}

你也许会问,为什么我没有编写MouseMove函数,它就自动的变大小了呢?这就是Track()函数的功劳,从调用它到抬起鼠标键为止,它时刻的改变m_rectTracker的四边形的大小。然后由于我们使用了Invalidate()函数,所以重新画了这个椭圆,因此它好象被放大缩小了似的。 我的文章写完了,还有什么不懂的地方,写信给我。在关闭这个文件之前,最好你自己再复习一下,并尝试一下其他的功能。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有