Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1676287
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2009-07-10 12:57:27

使用CRectTracker类进行对象动态定位(二)
2
内容提要:步骤五:使用AppWizard为CExamTrackerView增加WM_LBUTTONDOWN处理消息,在函数中我们必须处理三种情况;鼠标选中矩形对象但是不处于矩形边界,这种情况仅仅是对矩形进行移动...
步骤五:使用AppWizard为CExamTrackerView增加WM_LBUTTONDOWN处理消息,在函数中我们必须处理三种情况;鼠标选中 矩形对象但是不处于矩形边界,这种情况仅仅是对矩形进行移动,第二种情况:鼠标处于矩形边界,这时候拖动鼠标将会调整矩形的大小.第三种情况时鼠标没有选 中矩形的任何地方,这个时候将会产生橡皮条效果,橡皮条内的所有内容被选中.具体代码如下:
void CExamTrackerView::OnLButtonDown(UINT nFlags, CPoint point)
{
CExamTrackerDoc* pDoc = GetDocument();
  CRect rectSave;
  //获取图形区域矩形对象的大小
  pDoc->m_tracker.GetTrueRect(rectSave);
  //如果没有点中图形,这时候HitTest将返回-1.这时候产生橡皮条.
  if (pDoc->m_tracker.HitTest(point) < 0)
  {
    CRectTracker tracker;
    //画橡皮擦
    if (tracker.TrackRubberBand(this, point, pDoc->m_bAllowInvert))
    {
      // 下面的工作将用来检查橡皮条的矩形是否与图形区域的矩形相交.
      CRect rectT;
      //对橡皮条的矩形进行校正.
      tracker.m_rect.NormalizeRect(); // so intersect rect works
      //橡皮条区域与图形区域的交叉区域不为空,则将图形区域的调整句柄进行相应
      //的设置
      if (rectT.IntersectRect(tracker.m_rect, pDoc->m_tracker.m_rect))
      {
            //如果调整句柄位于矩形内部(resizeInside)则将调整句柄设置在矩形的外
//部(resizeOutside)
            if (pDoc->m_tracker.m_nStyle & CRectTracker::resizeInside)
            {
               //去除resizeInside 形式
              pDoc->m_tracker.m_nStyle &= ~CRectTracker::resizeInside;
               //设置resizeOutside形式
              pDoc->m_tracker.m_nStyle |= CRectTracker::resizeOutside;
            }
            //否则如果调整句柄在外部就将调整句柄放在区域内部
            else
            {
              // just use inside resize handles on first time
              pDoc->m_tracker.m_nStyle &= ~CRectTracker::resizeOutside;
              pDoc->m_tracker.m_nStyle |= CRectTracker::resizeInside;
            }
            //更新所有视图,显示调整后的图形
            pDoc->UpdateAllViews(NULL, (LPARAM)(LPCRECT)rectSave);
            pDoc->UpdateAllViews(NULL);
      }
    }
  }
  //如果选中了图形区域,则调用Track函数自动处理,同时处理后更新视图即可.
  else if (pDoc->m_tracker.Track(this, point, pDoc->m_bAllowInvert))
  {
    // normal tracking action, when tracker is "hit"
    pDoc->UpdateAllViews(NULL, (LPARAM)(LPCRECT)rectSave);
    pDoc->UpdateAllViews(NULL);
 }
  CView::OnLButtonDown(nFlags, point);
}
步骤六:到目前程序的原型基本上已经定下了,可以运行了!运行结果试试看!但是运行中你会发现一个问题,在VC,Delphi中鼠标再不同的区域 可以有不同的形状,比如如果选中图形区域鼠标为十字形状,选中边界时成一字形.在程序中我们通过处理WM_SETCURSOR消息来获取这种效果。
BOOL CExamTrackerView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
  CExamTrackerDoc* pDoc = GetDocument();
  if (pWnd == this && pDoc->m_tracker.SetCursor(this, nHitTest))
    return TRUE; 
  return CView::OnSetCursor(pWnd, nHitTest, message);
}
    从上面的代码可以看出函数中仅仅是调用了CRectTracker自己的SetCursor函数,具体的处理过程我们已经不需要做了.
    写到这儿的时候程序已经基本上结束了,用鼠标可以做大部分的事情,剩下的事情就是位置和大小的微调了,具体的微调通过处理WM_KEYDOWN消息来实现.具体的代码如下。
void CExamTrackerView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
  CExamTrackerDoc* pDoc = GetDocument();
  switch (nChar)
  {
  //如果按下的是←
  case VK_LEFT:
    //按下←的同时按下了Shift键,将图像区域向左减少5个位置
    if(::GetKeyState(VK_SHIFT)&0xff00)
    {
      pDoc->m_tracker.m_rect.right=pDoc->m_tracker.m_rect.right-5;
      pDoc->UpdateAllViews(NULL);
    }
    //否则,图像将向左移动5个位置
    else
    {
      pDoc->m_tracker.m_rect.left=pDoc->m_tracker.m_rect.left-5;
      pDoc->m_tracker.m_rect.right=pDoc->m_tracker.m_rect.right-5;
      pDoc->UpdateAllViews(NULL);
    }
    break;
    //如果按下的是→case VK_RIGHT:
//按下→的同时按下了Shift键,将图像区域向右增加5个位置
if(::GetKeyState(VK_SHIFT)&0xff00)
{
pDoc-m_tracker.m_rect.right=pDoc-m_tracker.m_rect.right+5;
pDoc-UpdateAllViews(NULL);
}
//否则,图像将向右移动5个位置
else
{
pDoc-m_tracker.m_rect.left=pDoc-m_tracker.m_rect.left+5;
pDoc-m_tracker.m_rect.right=pDoc-m_tracker.m_rect.right+5;
pDoc-UpdateAllViews(NULL);
}
break;
//如果按下的是↑
case VK_UP:
//按下↑的同时按下了Shift键,将图像区域向上减少5个位置
if(::GetKeyState(VK_SHIFT)&0xff00)
{
pDoc-m_tracker.m_rect.bottom=pDoc-m_tracker.m_rect.bottom-5;
pDoc-UpdateAllViews(NULL);
}
//否则,图像将向上移动5个位置
else
{
pDoc-m_tracker.m_rect.top=pDoc-m_tracker.m_rect.top-5;
pDoc-m_tracker.m_rect.bottom=pDoc-m_tracker.m_rect.bottom-5;
pDoc-UpdateAllViews(NULL);
}
break;
//如果按下的是↓,图像将向下移动5个位置
case VK_DOWN:
if(::GetKeyState(VK_SHIFT)&0xff00)
{
pDoc-m_tracker.m_rect.bottom=pDoc-m_tracker.m_rect.bottom+5;
pDoc-UpdateAllViews(NULL);
}
else
{
pDoc-m_tracker.m_rect.top=pDoc-m_tracker.m_rect.top+5;
pDoc-m_tracker.m_rect.bottom=pDoc-m_tracker.m_rect.bottom+5;
pDoc-UpdateAllViews(NULL);
}
break;
}

CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

所有的任务都完成了,慢,还有通过工具栏改变区域边界的方法,我就提供一个吧,剩下的大家就看源代码吧,应该很简单的,大家都能看的懂,需要注意的是几种形式的不可兼容性,否则会出错,其余的我就不费笔墨和口舌了
void CExamTrackerDoc::OnSolidline()
{
CRect rectTrue;
m_tracker.GetTrueRect(&rectTrue);
m_tracker.m_nStyle &= ~CRectTracker::dottedLine;
m_tracker.m_nStyle ^= CRectTracker::solidLine;
UpdateAllViews(NULL, (LPARAM)(LPCRECT)rectTrue);
UpdateAllViews(NULL);
}所有的任务都完成了慢
}
阅读(647) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~