zoukankan      html  css  js  c++  java
  • CRectTracker类的使用

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

    1

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

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

    第一步:

    在CRectTrackeDoc类中生成一个公有的数据成员:m_RectTracker;之所以设成公有,因为要在View中调用它。

    class CRectTrackeDoc : public CDocument
    {
    protected: // create from serialization only
        CRectTrackeDoc();
        DECLARE_DYNCREATE(CRectTrackeDoc)
    
    // Attributes
    public:
        CRectTracker m_RectTracker;

    接着我们来初始化它,在CRectTrackeDoc构造函数中:

    CRectTrackeDoc::CRectTrackeDoc()
    {
        // TODO: add one-time construction code here
        m_RectTracker.m_rect.SetRect(200,200,100,100);            //矩形位置
    
        m_RectTracker.m_nStyle = CRectTracker::dottedLine | CRectTracker::resizeInside;
    }

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

    第二步:

    在CRectTrackeView 类中添加一个公有成员变量bDraw,用来判断是否需要在矩形框中画椭圆

    class CRectTrackeView : public CView
    {
    protected: // create from serialization only
        CRectTrackeView();
        DECLARE_DYNCREATE(CRectTrackeView)
    
    // Attributes
    public:
        CRectTrackeDoc* GetDocument();
        BOOL bDraw;

    在构造函数中初始化bDraw = false,表示初始时不在矩形宽中画椭圆,只有鼠标左键按下时,bDraw为true.才进行画椭圆操作

    CRectTrackeView::CRectTrackeView()
    {
        // TODO: add construction code here
         bDraw = FALSE;
    }

    第三步:

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

    void CRectTrackeView::OnDraw(CDC* pDC)
    {
        CRectTrackeDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
    
        CBrush brush(RGB(0,0,255));
        CBrush * oldBrush = pDC->SelectObject(&brush);
        CRect rect;
    
        pDoc->m_RectTracker.GetTrueRect(&rect); //得到CRectTracker中的m_rect的大小,将其传递给rect;
    
        if(bDraw) 
        {    
            pDC->Ellipse(&rect);
        }
    
        pDoc->m_RectTracker.Draw(pDC);            //这句画才真正的将这个四边形画出来;
    
        pDC->SelectObject(oldBrush);
    
        // TODO: add draw code for native data here
    }

    这个时候运行程序,将会看到在视类客户区200,200,100,100的位置出现一个矩形区域,因为bDraw参数为false,此时并没有画出椭圆。如下图:

    2

    第四步:

    如何像例子中的那样随着鼠标的移动自动在椭圆的周围改变光标呢?很简单只要将下面的代码加入到CRectTrackeView::OnSetCursor()就可以了:它调用了CRectTracker中的SetCursor()函数。 注意:OnSetCursor是一个消息响应函数,当鼠标在改矩形区域中的时候,会产出消息,并调用OnSetCursor函数。

    BOOL CRectTrackeView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
    {
        // TODO: Add your message handler code here and/or call default
    
        CRectTrackeDoc* pDoc = GetDocument();
    
        if((pWnd == this) && (pDoc->m_RectTracker.SetCursor(this,nHitTest)))
        {
            return TRUE;
        }
        
        return CView::OnSetCursor(pWnd, nHitTest, message);
    }

    编译运行一下,鼠标变化了。

    第五步:

    添加鼠标左键按下消息响应函数,该函数功能呢:当在矩形区域内点击左键并拖动的时候,则在矩形区域内把椭圆绘制出来, 当在矩形区域外点击鼠标左键并拖动的时候,则重新绘制一个矩形区域。运行结果如第一张图。

    void CRectTrackeView::OnLButtonDown(UINT nFlags, CPoint point) 
    {
        // TODO: Add your message handler code here and/or call default
    
        //判断鼠标点击的区域是在哪里,在在矩形区域内,还是区域外
        int nRetCode = GetDocument()->m_RectTracker.HitTest(point);
    
        if(nRetCode < 0)            //不在矩形区域
        {
            //给temp变量初始化
            CRectTracker  temp;
             temp.m_rect.SetRect(0,0,0,0);
             temp.m_nStyle = CRectTracker::dottedLine | CRectTracker::resizeInside;
    
            //TrackRubberBand函数直到鼠标左键提起的时候才会返回,并把左键提起的位置也记录了下来
            //该函数过程中,不会产生鼠标移动消息
            temp.TrackRubberBand(this,point,TRUE);
            //使得矩形为正确的坐标,不会出现负的坐标
            temp.m_rect.NormalizeRect();
            //此时把bDraw设为false
             bDraw = FALSE;
             CClientDC dc(this);
            //把新的矩形区域绘制出来
            temp.Draw(&dc);
        }
        else                        //在矩形区域内
        {
            //Track和TrackRubberBand类似,直到鼠标左键提起的时候才会返回,并把左键提起的位置也记录了下来
            //该函数过程中,不会产生鼠标移动消息
            GetDocument()->m_RectTracker.Track(this,point,TRUE);
            //设置为true,则需要在矩形内绘制椭圆
            bDraw = TRUE;
    
            //窗口无效,调用Onpaint函数
            Invalidate(TRUE);
        }
        
        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)的功能:当你鼠标被按下的时候,你可以调用这个函数,它将返回鼠标点在了四边形的什么位置:

    3

    以上就是CRectTracker类的用法。

  • 相关阅读:
    【分享】HTML5附件拖拽上传drop & google.gears
    【分享】return false,对阻止事件默认动作的一些测试
    【记录】随笔分类汇总
    【分享】微博 @ 符号的用户名提示效果。(想@到谁?)
    【记录】File, FileReader 和 Ajax 文件上传
    【动态】简单的JS动态加载单体
    【分享】简单页面提示插件第二版表单验证很简单
    【记录】GIT 常用命令
    【分享】jQuery animate自定义动画的简单实现
    【分享】 封装js操作textarea 方法集合(兼容很好)。
  • 原文地址:https://www.cnblogs.com/xydblog/p/3475552.html
Copyright © 2011-2022 走看看