Windows自带的画图软件中可以用虚线框选择图像的某个区域,之后便可以拖动、放大、缩小该区域,这是通过橡皮筋类(CRectTracker)来实现的,它将实现用线框选中一个区域,并可以拖动、放大、缩小该区域。 简介: CRectTracker类允许一个项被显示,移动,以不同的方式改变大小。虽然CRectTracker类是设计来支持用户以图形化界面与OLE项交互的,但是它的使用不仅限于支持OLE的应用程序。它可以使用在任何需要用户界面的地方。 CRectTracker的边框可以是实线,也可以是点线。可给予项一种阴影式边框或用一种阴影样式覆盖项,用来指示项的不同状态。你可以在项的外界或内部放置八个调整大小把手。(有关八个调整大小把手的解释,参见GetHandleMask。)最后,一个CRectTracker允许你在调整项的大小时改变项的方向。 要使用CRectTracker,首先要构造一个CRectTracker对象,并指定用哪种显示状态来初始化。然后,应用程序就可以使用这个界面,提供给用户有关与CRectTracker对象相关联的OLE项当前状态的直观反馈了。 #include 请参阅: COleResizeBar, CRect, CRectTracker::GetHandleMask CRectTracker类成员 数据成员 m_nHandleSize | 确定调整大小把手的尺寸 | m_rect | 矩形的以像素表示的当前位置 | m_sizeMin | 确定矩形宽度和高度的最小值 | m_nStyle | 跟踪器的当前风格 | 构造 操作 Draw | 显示矩形 | GetTrueRect | 返回矩形的宽度和高度,包括改变大小句柄 | HitTest | 返回与CRectTracker对象关联的光标的当前位置 | NormalizeHit | 规范化一个单击测试代码 | SetCursor | 根据光标在矩形上方的位置来设置光标 | Track | 支持用户操作矩形 | TrackRubberBand | 支持用户“橡皮筋”似的拉伸选择 | 可重载 AdjustRect | 当矩形被改变大小时此函数被调用 | DrawTrackerRect | 当画一个CRectTracker对象的边框时此函数被调用 | OnChangedRect | 当矩形被改变大小或被移动时,此函数被调用 | GetHandleMask | 调用此函数来获得一个CRectTracker项的调整大小把手的掩码 | 1.新建一个单文档应用程序,命名为CRectTracker,完成。 2.在CCRectTrackerView中新建一个CRectTracker类型的成员变量m_RectTracker,和BOOL类型的变量m_IsChosen,表示是否选择了, CCRectTrackerView::CCRectTrackerView() { m_RectTracker.m_rect.SetRect(10,10,100,100);//设置矩形区域大小 m_RectTracker.m_nStyle=CRectTracker::dottedLine|CRectTracker::resizeInside; m_IsChosen=FALSE;//表示未选中 } m_nStyle是设置CRectTracker对象的框的属性,其中CRectTracker::dottedLine表示该外框是虚线框,CRectTracker::resizeInside表示在该区域内部改变大小。 3. void CCRectTrackerView::OnLButtonDown(UINT nFlags, CPoint point) { if(m_RectTracker.HitTest(point)<0) { CRectTracker tempRectTracker; CRect rect; tempRectTracker.TrackRubberBand(this,point); tempRectTracker.m_rect.NormalizeRect(); if(rect.IntersectRect(tempRectTracker.m_rect,m_RectTracker.m_rect)) m_IsChosen=TRUE; else m_IsChosen=FALSE; Invalidate(); } else { CClientDC dc(this); m_RectTracker.Draw(&dc); m_RectTracker.Track(this,point); m_IsChosen=TRUE; Invalidate(); } CView::OnLButtonDown(nFlags, point); } HitTest(point)是用point测试鼠标在区域的什么位置,如下表
返回值 | 代表的含义 | -1 | 点在了四边形的外部 | 0 | 左上角 | 1 | 右上角 | 2 | 右下角 | 3 | 左下角(0,1,2,3顺时针转了一圈) | 4 | 顶部 | 5 | 右部 | 6 | 底部 | 7 | 左部(还是顺时针转了一圈) | 8 | 点在了四边形的内部,但没有击中前面的那八个点 | TrackRubberBand表示跟踪橡皮筋的边框,其中this表示拥有该虚线框的窗口,point表示虚线框的起始点,TRUE表示可以往任意方向画虚线框,若为FALSE,只能往右下画虚线框。TrackRubberBand是以左键弹起作为结束,在此期间不能响应WM_MOUSEMOVE消息,弹起也收不到WM_LBUTTONUP消息。下面会介绍如何获得WM_LBUTTONUP消息。 m_rect.NormalizeRect()是为了防止TrackRubberBand第三个参数为FALSE引起的错误而实施的正规化。 CRect::IntersectRect(rect1,rect2)表示rect1和rect2是否有交集. 用CRectTracker::Draw(&dc)绘制矩形区域的8个点以及边框线. Track(this,point);用来实时更新矩形的变化,是最有魅力的函数,拖动,改变大小都是由它指挥完成,其中this表示拥有该矩形的窗口,point是起始点。左键弹起作为结束,在此期间也不能响应WM_MOUSEMOVE消息。 4. 重载CCRectTrackerView::OnSetCursor BOOL CCRectTrackerView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if(pWnd==this && m_RectTracker.SetCursor(this,nHitTest)) return TRUE; return CView::OnSetCursor(pWnd, nHitTest, message); } CRectTracker::SetCursor(this,nHitTest)用来捕捉鼠标,当鼠标在该区域里或区域边框上时会产生不同的鼠标图案,如在区域里就是十字形的,在边框上8点不同位置也有不同图案,此时返回TRUE;在矩形外面就返回FALSE;然后直接返回TRUE不让视类处理该消息。 5. void CCRectTrackerView::OnDraw(CDC* pDC) { CCRectTrackerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; //自己添加 CBrush brush(RGB(255,0,0));//画刷为红色 CBrush *pbrush=pDC->SelectObject(&brush); CRect rect; m_RectTracker.GetTrueRect(&rect);//得到矩形区域的大小 pDC->Rectangle(&rect);//画出矩形 if(m_IsChosen) m_RectTracker.Draw(pDC);//若选择了该区域,则显示边框以及8个调整点 } 这样就可以完成本实例的功能了!但若要在WM_LBUTTONUP里处理某些特殊的要求,只需在CRectTracker::TrackRubberBand、CRectTracker::Track下发送WM_LBUTTONUP消息即可, 即SendMessage(WM_LBUTTONUP,NULL,NULL)便可以实现了.
|