The CRectTracker class is useful in both OLE and non-OLE programs. It allows the user to move and resize a rectangular object in a view window. There are two important data members: the m_nStyle member determines the border, resize handle, and other characteristics; and the m_rect member holds the device coordinates for the rectangle.
The important member functions follow.
The Draw function draws the tracker, including border and resize handles, but it does not draw anything inside the rectangle. That's your job.
You call this function in a WM_LBUTTONDOWN handler. If the cursor is on the rectangle border, the user can resize the tracker by holding down the mouse button; if the cursor is inside the rectangle, the user can move the tracker. If the cursor is outside the rectangle, Track returns FALSE immediately; otherwise, Track returns TRUE only when the user releases the mouse button. That means Track works a little like CDialog::DoModal. It contains its own message dispatch logic.
Call HitTest if you need to distinguish between mouse button hits inside and on the tracker rectangle. The function returns immediately with the hit status in the return value.
Call this function in your view's WM_SETCURSOR handler to ensure that the cursor changes during tracking. If SetCursor returns FALSE, call the base class OnSetCursor function; if SetCursor returns TRUE, you return TRUE.
You must deal with the fact that the CRectTracker::m_rect member stores device coordinates. If you are using a scrolling view or have otherwise changed the mapping mode or viewport origin, you must do coordinate conversion. Here's a strategy:
m_tracker.m_rect = m_rectTracker; pDC->LPtoDP(m_tracker.m_rect); // tracker requires device // coordinates m_tracker.Draw(pDC);
if (m_tracker.Track(this, point, FALSE, NULL)) { CClientDC dc(this); OnPrepareDC(&dc); m_rectTracker = m_tracker.m_rect; dc.DPtoLP(m_rectTracker); Invalidate(); }