⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recttracker.cpp

📁 BCAM 1394 Driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  return TrackHandle(hitBottomRight, hWnd, point);
}


void CRectTracker::AdjustRect(int nHandle, LPRECT)
{
  if (nHandle == hitMiddle)
    return;


  // convert the handle into locations within m_rect
  int *px, *py;
  GetModifyPointers(nHandle, &px, &py, NULL, NULL);

  // enforce minimum width
  int nNewWidth = m_rect.Width();
  int nAbsWidth = m_bAllowInvert ? abs(nNewWidth) : nNewWidth;
  if (px != NULL && nAbsWidth < m_sizeMin.cx)
  {
    nNewWidth = nAbsWidth != 0 ? nNewWidth / nAbsWidth : 1;
    ATLASSERT((int*)px - (int*)&m_rect < _countof(RectInfo));
    const RECTINFO* pRectInfo = &RectInfo[(int*)px - (int*)&m_rect];
    *px = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
      nNewWidth * m_sizeMin.cx * -pRectInfo->nSignAcross;
  }

  // enforce minimum height
  int nNewHeight = m_rect.Height();
  int nAbsHeight = m_bAllowInvert ? abs(nNewHeight) : nNewHeight;
  if (py != NULL && nAbsHeight < m_sizeMin.cy)
  {
    nNewHeight = nAbsHeight != 0 ? nNewHeight / nAbsHeight : 1;
    ATLASSERT((int*)py - (int*)&m_rect < _countof(RectInfo));
    const RECTINFO* pRectInfo = &RectInfo[(int*)py - (int*)&m_rect];
    *py = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
      nNewHeight * m_sizeMin.cy * -pRectInfo->nSignAcross;
  }
}

void CRectTracker::GetTrueRect(LPRECT lpTrueRect) const
{

  CRect rect = m_rect;
  rect.NormalizeRect();
  LPtoDP((LPPOINT) &rect, 2);
  int nInflateBy = 0;
  if ((m_nStyle & (resizeOutside|hatchedBorder)) != 0)
    nInflateBy += GetHandleSize() - 1;
  if ((m_nStyle & (solidLine|dottedLine)) != 0)
    ++nInflateBy;
  rect.InflateRect(nInflateBy, nInflateBy);
  *lpTrueRect = rect;
}

void CRectTracker::OnChangedRect(const CRect& /*rectOld*/)
{
  // no default implementation, useful for derived classes
}

void CRectTracker::OnTrackingFinished(const BOOL bCancelled )
{
  // no default implementation, useful for derived classes
}

/////////////////////////////////////////////////////////////////////////////
// CRectTracker implementation helpers

void CRectTracker::GetHandleRect(int nHandle, CRect* pHandleRect) const
{
  ATLASSERT(nHandle < 8);

  // get normalized rectangle of the tracker
  CRect rectT = m_rect;
  rectT.NormalizeRect();
  LPtoDP((LPPOINT) &rectT, 2);
  if ((m_nStyle & (solidLine|dottedLine)) != 0)
    rectT.InflateRect(+1, +1);

  // since the rectangle itself was normalized, we also have to invert the
  //  resize handles.
  nHandle = NormalizeHit(nHandle);

  // handle case of resize handles outside the tracker
  int size = GetHandleSize();
  if (m_nStyle & resizeOutside)
    rectT.InflateRect(size-1, size-1);

  // calculate position of the resize handle
  int nWidth = rectT.Width();
  int nHeight = rectT.Height();
  CRect rect;
  const HANDLEINFO* pHandleInfo = &HandleInfo[nHandle];
  rect.left = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetX);
  rect.top = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetY);
  rect.left += size * pHandleInfo->nHandleX;
  rect.top += size * pHandleInfo->nHandleY;
  rect.left += pHandleInfo->nCenterX * (nWidth - size) / 2;
  rect.top += pHandleInfo->nCenterY * (nHeight - size) / 2;
  rect.right = rect.left + size;
  rect.bottom = rect.top + size;

  *pHandleRect = rect;
}

int CRectTracker::GetHandleSize(LPCRECT lpRect) const
{
  if (lpRect == NULL)
    lpRect = &m_rect;

  int size = m_nHandleSize;
  if (!(m_nStyle & resizeOutside))
  {
    // make sure size is small enough for the size of the rect
    int sizeMax = min(abs(lpRect->right - lpRect->left),
      abs(lpRect->bottom - lpRect->top));
    if (size * 2 > sizeMax)
      size = sizeMax / 2;
  }
  return size;
}

int CRectTracker::HitTestHandles(CPoint point) const
{
  CRect rect;
  UINT mask = GetHandleMask();

  // see if hit anywhere inside the tracker
  GetTrueRect(&rect);
  if (!rect.PtInRect(point))
    return hitNothing;  // totally missed

  // see if we hit a handle
  for (int i = 0; i < 8; ++i)
  {
    if (mask & (1<<i))
    {
      GetHandleRect((TrackerHit)i, &rect);
      if (rect.PtInRect(point))
        return (TrackerHit)i;
    }
  }

  // last of all, check for non-hit outside of object, between resize handles
  if ((m_nStyle & hatchedBorder) == 0)
  {
    CRect rect = m_rect;
    rect.NormalizeRect();
    if ((m_nStyle & dottedLine|solidLine) != 0)
      rect.InflateRect(+1, +1);
    if (!rect.PtInRect(point))
      return hitNothing;  // must have been between resize handles
  }
  return hitMiddle;   // no handle hit, but hit object (or object border)
}

BOOL CRectTracker::TrackHandle(int nHandle, HWND hWnd, CPoint point)
{

  if ( m_bIsTracking )
    return FALSE;  // we are already tracking;
  // don't handle if capture already set
  if (::GetCapture() != NULL)
    return FALSE;

  m_nHandle = nHandle;
  CWindow Wnd(hWnd);

  ATLASSERT(nHandle >= 0);
  ATLASSERT(nHandle <= 8);   // handle 8 is inside the rect

  DPtoLP(&point);


  // set capture to the window which received this message
  Wnd.SetCapture();
  ATLASSERT(Wnd.m_hWnd == ::GetCapture());
  Wnd.UpdateWindow();

  // find out what x/y coords we are supposed to modify
  CPoint pt;
  CPoint Diff;
  GetModifyPointers(nHandle, &m_px, &m_py, (int*) &m_Diff.x, (int*) &m_Diff.y);
  m_Diff.x = point.x - m_Diff.x;
  m_Diff.y = point.y - m_Diff.y;

  m_bIsTracking = TRUE;
  m_bChanged = FALSE;


  AdjustRect(m_nHandle, &m_rect);


  return TRUE;


}

// a client  has to call this message handler 

BOOL CRectTracker::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam)
{

  CPoint pt;
  CRect rectOld;
  BOOL bHandled = FALSE;
  int nWidth, nHeight;

  if ( ! m_bIsTracking )
    return bHandled;
 
  switch (uMsg)
  {
    // handle movement/accept messages
  case WM_MOUSEMOVE:
  case WM_LBUTTONUP:
    bHandled = TRUE;
    rectOld = m_rect;
    // save original width & height in pixels
    nWidth = m_rect.Width();
    nHeight = m_rect.Height();
    
    // handle resize cases (and part of move)
    pt.x = (int)(short)LOWORD(lParam);
    pt.y = (int)(short)HIWORD(lParam);
    DPtoLP(&pt);
    if (m_px != NULL)
      *m_px = pt.x - m_Diff.x;
    if (m_py != NULL)
      *m_py = pt.y - m_Diff.y;
    
    // handle move case
    if (m_nHandle == hitMiddle)
    {
      m_rect.right = m_rect.left + nWidth;
      m_rect.bottom = m_rect.top + nHeight;
    }
    // allow caller to adjust the rectangle if necessary
    AdjustRect(m_nHandle, &m_rect);
    
    // only callback if the rect actually changed
    if (!rectOld.EqualRect(&m_rect)  )
    {
      OnChangedRect(rectOld);
      m_bChanged = TRUE;
    }
    if ( uMsg == WM_LBUTTONUP )
    {
      // finish tracking
      if ( m_bChanged ) 
      {
        m_bIsTracking = false;
        ReleaseCapture();
        m_nHandle = hitNothing;
        OnTrackingFinished( FALSE ); 
      }
      else
      {
        CancelTracking();
      }
    }
    break;
    // handle cancel messages
  case WM_KEYDOWN:
    if (wParam != VK_ESCAPE)
    {
      break;
    }
  case WM_CAPTURECHANGED:
    // we lost the mouse capture -> cancel
  case WM_RBUTTONDOWN:
    CancelTracking();
    bHandled = TRUE;
    break;
  }

  return bHandled;
}

void CRectTracker::CancelTracking()
{
  if ( m_bIsTracking )
  {
    m_rect = m_rectSave;
    m_bIsTracking = false;
    m_nHandle = hitNothing;
    OnTrackingFinished(TRUE);
    ReleaseCapture();
  }
}


void CRectTracker::GetModifyPointers(
  int nHandle, int** ppx, int** ppy, int* px, int* py)
{
  ATLASSERT(nHandle >= 0);
  ATLASSERT(nHandle <= 8);

  if (nHandle == hitMiddle)
    nHandle = hitTopLeft;   // same as hitting top-left

  *ppx = NULL;
  *ppy = NULL;

  // fill in the part of the rect that this handle modifies
  //  (Note: handles that map to themselves along a given axis when that
  //   axis is inverted don't modify the value on that axis)

  const HANDLEINFO* pHandleInfo = &HandleInfo[nHandle];
  if (pHandleInfo->nInvertX != nHandle)
  {
    *ppx = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetX);
    if (px != NULL)
      *px = **ppx;
  }
  else
  {
    // middle handle on X axis
    if (px != NULL)
      *px = m_rect.left + abs(m_rect.Width()) / 2;
  }
  if (pHandleInfo->nInvertY != nHandle)
  {
    *ppy = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetY);
    if (py != NULL)
      *py = **ppy;
  }
  else
  {
    // middle handle on Y axis
    if (py != NULL)
      *py = m_rect.top + abs(m_rect.Height()) / 2;
  }
}

UINT CRectTracker::GetHandleMask() const
{
  UINT mask = 0x0F;   // always have 4 corner handles
  int size = m_nHandleSize*3;
  if (abs(m_rect.Width()) - size > 4)
    mask |= 0x50;
  if (abs(m_rect.Height()) - size > 4)
    mask |= 0xA0;
  return mask;
}

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -