1. Base concept and principle on how to use CRectTracker:
Allows an item to be displayed, moved, and resized in different fashions.
--Form MSDN
Example to use this (when you drag the mouse, the RectTracker comes):
1) QQ Snap Desktop picture;
2) Windows explorer;
....
2. Important member funtions of CRectTracker:
SetRect // set the rect of rect tracker
Track // change the position of rect tracker
SetCursor // Change the cursor
HitTest
Draw // draw the rect tracker
Refer MSDN for the Detail.
3. Take an example to show how to use the CRectTracker.
Implement goal show as the follow picture:
Environment VS 2008 Windows XP EN
1) start a MFC dialog project named tracker
2) Add three member:
CRectTracker m_tracker; // CRectTracker object
CPoint m_start; // the the mouse down, record the start point here
BOOL m_bDraw; // whether draw
3) Add a WM_LBUTTONDOWN handle function(OnLButtonDown)
void CtrackerDlg::OnLButtonDown(UINT nFlags, CPoint point)
...{
int nHitTest;
nHitTest = m_tracker.HitTest(point);
if ( nHitTest < 0 ) // if the mouse down point is outside of the rect tracker
...{
m_start = point; // Record the start drawing point
m_bDraw = TRUE; // set m_bDraw (in handle funtion WM_MOUSEMOVE will test this to decide whether to draw)
}
else // if the mouse down point is outside of the rect tracker
...{
m_tracker.Track(this,point,TRUE); // start drag the rect tracker
this->Invalidate(); // make the window paint to refresh the track
}
CDialog::OnLButtonDown(nFlags, point);
}
4)Add a WM_MOUSEMOVE handle funtion(OnMouseMove)
void CtrackerDlg::OnMouseMove(UINT nFlags, CPoint point)
...{
// m_bDraw is set to true in funtion OnLButtonDown and set to false in funtion OnLButtonDown
// m_bDraw is use for testing if the mouse is moved along with the left button is pressed.
if(m_bDraw)
...{
m_tracker.m_rect.SetRect(m_start,point); // set the rect of rect tracker
this->Invalidate(); // make the window paint to refresh the rect
}
CDialog::OnMouseMove(nFlags, point);
}
5)Add a WM_LBUTTONUP handle funtion(OnLButtonUp)
void CtrackerDlg::OnLButtonUp(UINT nFlags, CPoint point)
// After the mouse up, when moving the mouse, do nothing.
m_bDraw = FALSE;
}
6)Add a WM_SETCURSOR handle funtion(OnSetCursor) to hanld the change of the Cursor
BOOL CtrackerDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
...{
if (pWnd == this && m_tracker.SetCursor(this, nHitTest))
...{
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
6)Draw the Rect track rect in OnPaint function of the dialog
void CtrackerDlg::OnPaint()
...{
if (IsIconic())
...{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in clIEnt rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClIEntRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
...{
// the follow two lines is added
CPaintDC dc(this);
m_tracker.Draw(&dc);
CDialog::OnPaint();
}
}7) Don’t forget to init the var on OnInitDialog with follow:
// TODO: Add extra initialization here
m_tracker.m_rect.SetRect(-1,-1,-1,-1);
m_tracker.m_nStyle=CRectTracker::resizeOutside|CRectTracker::dottedLine;
m_bDraw = FALSE;
Notice:
When you compile it with a share MFC lib, there is no problem here, but when you compile it with a static MFC, the cursor cannot be show when you use “m_tracker.SetCursor”, that means: consider that you move your mouse to resize the rect, when your cursor on the change point of the rect, the cursor disappeared.
That because of the resource of such cursor are not loaded. To avoid this, just need to delete one line
#define _AFX_NO_TRACKER_RESOURCES
in your “*.RC” file. To my confuse, you must delete it twice(open->delete this line ->build code-> open again -> delete it again)