橡皮筋类(CRectTracker)

来源:互联网 发布:mac可以下载企业qq吗 编辑:程序博客网 时间:2024/04/27 22:37

Windows自带的画图软件中可以用虚线框选择图像的某个区域,之后便可以拖动、放大、缩小该区域,这是通过橡皮筋类(CRectTracker)来实现的,它将实现用线框选中一个区域,并可以拖动、放大、缩小该区域。

简介:

CRectTracker类允许一个项被显示,移动,以不同的方式改变大小。虽然CRectTracker类是设计来支持用户以图形化界面与OLE项交互的,但是它的使用不仅限于支持OLE的应用程序。它可以使用在任何需要用户界面的地方。 
  CRectTracker的边框可以是实线,也可以是点线。可给予项一种阴影式边框或用一种阴影样式覆盖项,用来指示项的不同状态。你可以在项的外界或内部放置八个调整大小把手。(有关八个调整大小把手的解释,参见GetHandleMask。)最后,一个CRectTracker允许你在调整项的大小时改变项的方向。 
  要使用CRectTracker,首先要构造一个CRectTracker对象,并指定用哪种显示状态来初始化。然后,应用程序就可以使用这个界面,提供给用户有关与CRectTracker对象相关联的OLE项当前状态的直观反馈了。 
  #include <afxext.h> 
  请参阅: 
  COleResizeBar, CRect, CRectTracker::GetHandleMask 
  CRectTracker类成员 
  数据成员

m_nHandleSize确定调整大小把手的尺寸m_rect矩形的以像素表示的当前位置m_sizeMin确定矩形宽度和高度的最小值m_nStyle跟踪器的当前风格
  构造CRectTracker构造一个CRectTracker对象
  操作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)便可以实现了.