CRectTracker类的使用 CRectTracker(俗称“橡皮筋”类)是一个非常有意思的类。你在Windows中经常看到这样的情况:它可以用做显示边界,你也可以扽它的八个角用来放大缩小,或做框选使用。如何通过编程来实现这种功能呢?这就是CRectTracker类的作用; 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; }
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试试看各参数的含义; 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类。它的作用是在鼠标按下以后可以显示虚线的选择框: 先让我们看看效果: void CRectView::OnLButtonDown(UINT nFlags, CPoint point) { CRectTracker temp; temp.TrackRubberBand(this,point,TRUE); temp.m_rect.NormalizeRect();//正规化; CView::OnLButtonDown(nFlags, point); }
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()函数,所以重新画了这个椭圆,因此它好象被放大缩小了似的。 我的文章写完了,还有什么不懂的地方,写信给我。在关闭这个文件之前,最好你自己再复习一下,并尝试一下其他的功能。 |