• CRectTracker类的使用--橡皮筋窗口


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

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

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

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

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

    第一步:

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

    1.CRectDoc::CRectDoc()
    2.// TODO: add one-time construction code here
    3.m_rectTracker.m_rect.SetRect(0,0,100,100);
    4.m_rectTracker.m_nStyle=CRectTracker
    5.::resizeInside|CRectTracker::dottedLine;
    6.}

    其中: 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中继续我们的工作:

    01.void CRectView::OnDraw(CDC* pDC)
    02.{
    03.CRectDoc* pDoc = GetDocument();
    04.ASSERT_VALID(pDoc);
    05.// TODO: add draw code for native data here
    06.CBrush brush(RGB(0,0,255));//生成蓝色的画刷;
    07.CBrush  *oldBrush=pDC->SelectObject(&brush);//将画刷选进dc;
    08.CRect rect;
    09.//GetTrueRect(&rect)得到CRectTracker中的m_rect的大小,将其传递给rect;
    10.pDoc->m_rectTracker.GetTrueRect(&rect);
    11.pDC->Ellipse (rect);//画椭圆;
    12.//Draw tracking rectangle.
    13.pDoc->m_rectTracker.Draw(pDC);//这句画才真正的将这个四边形画出来;
    14.//Select blue brush out of device context.
    15.pDC->SelectObject (oldBrush);//恢复原来的画刷;
    16.}

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

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

    1.BOOL CRectView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
    2.// TODO: Add your message handler code here and/or call default
    3.CRectDoc* pDoc  = GetDocument();
    4.if (pWnd == this && pDoc->m_rectTracker.SetCursor(this, nHitTest))
    5.return TRUE;
    6.return CView::OnSetCursor(pWnd, nHitTest, message);
    7.}

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

    在CRectView中的加入如下代码:

    1.void CRectView::OnLButtonDown(UINT nFlags, CPoint point)
    2.{
    3.CRectTracker temp;
    4.temp.TrackRubberBand(this,point,TRUE);
    5.temp.m_rect.NormalizeRect();//正规化;
    6.CView::OnLButtonDown(nFlags, point);
    7.}

    编译运行,当你按下鼠标并拖动,你将看到效果了。 
    我们如何让鼠标画一个“橡皮筋”区域呢? 在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时,表示要画边界。 定义:

    01.class CRectView : public CView
    02.{
    03.…………
    04.public:
    05.BOOL bDraw;
    06.…….
    07.}
    08.初始化:
    09.CRectView::CRectView()
    10.{
    11.// TODO: add construction  code here
    12.bDraw=FALSE;
    13.}
    14.将OnDraw改一下,加一句话:
    15.void CRectView::OnDraw(CDC* pDC)
    16.{
    17.CRectDoc* pDoc = GetDocument();
    18.ASSERT_VALID(pDoc);
    19.// TODO: add draw code for  native data here
    20.CBrush brush(RGB(0,0,255));//生成蓝色的画刷;
    21.CBrush  *oldBrush=pDC->SelectObject(&brush);//将画刷选进dc;
    22.CRect  rect;
    23.pDoc->m_rectTracker.GetTrueRect (&rect);
    24.//GetTrueRect(&rect)可以得到CRectTracker中的m_rect的大小,将其传递给rect;
    25.if(bDraw) //*************新加的语句***************
    26.pDC->Ellipse (rect);//画椭圆;
    27.//Draw tracking rectangle.
    28.pDoc->m_rectTracker.Draw (pDC);//***这句画才真正的将这个四边形画出来;***
    29.//Select blue brush out  of device context.
    30.pDC->SelectObject (oldBrush);//恢复原来的画刷;
    31.}
    32.编译运行一下,椭圆的边界没有了。
    33.好了,预备知识讲完了,让我们来完成这个程序吧:
    34.void CRectView::OnLButtonDown(UINT nFlags, CPoint point)
    35.{
    36.// TODO: Add your message  handler code here and/or call default
    37.int nIn; //定义一个鼠标的点击值;
    38.nIn=GetDocument()->m_rectTracker.HitTest(point); //看看点到了哪了
    39.if(nIn<0)  //不在四边形区域内;
    40.{
    41.CRectTracker  temp;
    42.temp.TrackRubberBand(this,point,TRUE);
    43.temp.m_rect.NormalizeRect();
    44.CRectTracker interRect;
    45.//在建立一个CRectTracker;用于记录鼠标与椭圆的交集。
    46.if(interRect.m_rect.IntersectRect(temp.m_rect,GetDocument()->m_rectTracker.m_rect))
    47.bDraw=TRUE; //如果有交集,则画四边形的边界,说明选择了椭圆
    48.else   bDraw=FALSE;
    49.Invalidate(); //引起OnDraw函数的发生;
    50.}
    51.else
    52.//在四边形区域内:
    53.{
    54.CClientDC dc(this);
    55.GetDocument()->m_rectTracker.Draw(&dc);
    56.GetDocument()->m_rectTracker.Track(this,point,TRUE);
    57.// Track()是CRectTracker中最富魅力的函数。它时时的改变调用者的m_rect;
    58.bDraw=TRUE;
    59.Invalidate();
    60.}
    61.CView::OnLButtonDown(nFlags, point);
    62.}

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

  • 相关阅读:
    AIMS 2013中的性能报告工具不能运行的解决办法
    读懂AIMS 2013中的性能分析报告
    在线研讨会网络视频讲座 方案设计利器Autodesk Infrastructure Modeler 2013
    Using New Profiling API to Analyze Performance of AIMS 2013
    Map 3D 2013 新功能和新API WebCast视频下载
    为Autodesk Infrastructure Map Server(AIMS) Mobile Viewer创建自定义控件
    ADN新开了云计算Cloud和移动计算Mobile相关技术的博客
    JavaScript修改css样式style
    文本编辑神器awk
    jquery 开发总结1
  • 原文地址:https://www.cnblogs.com/lidabo/p/3710091.html
Copyright © 2020-2023  润新知