CRectTracker 是 MFC 提供的強大類別,俗稱「橡皮筋類別」。它能實現:矩形邊框顯示、八個控制點縮放、框選區域 (Rubber Band) 等功能,廣泛用於繪圖編輯器、圖片裁剪工具等場合。本文透過建立一個單文檔專案 Rect,循序漸進示範其核心功能。
RectCRectDoc 加入公有成員:CRectTracker m_rectTracker;CRectDoc::CRectDoc() {
m_rectTracker.m_rect.SetRect(0, 0, 100, 100); // 初始矩形 (View 座標)
m_rectTracker.m_nStyle = CRectTracker::resizeInside | CRectTracker::dottedLine;
}
樣式說明:
resizeInside/Outside:控制點在矩形內/外dottedLine/solidLine:虛線/實線邊框 (互斥)hatchedBorder:斜紋邊框hatchInside:內部斜紋填充OnDraw)void CRectView::OnDraw(CDC* pDC) {
CRectDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CBrush brush(RGB(0, 0, 255)); // 藍色筆刷
CBrush* oldBrush = pDC->SelectObject(&brush);
CRect rect;
pDoc->m_rectTracker.GetTrueRect(&rect); // 取得追蹤矩形
pDC->Ellipse(rect); // 畫橢圓
pDoc->m_rectTracker.Draw(pDC); // 畫追蹤邊框與控制點
pDC->SelectObject(oldBrush);
}
OnSetCursor)BOOL CRectView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) {
CRectDoc* pDoc = GetDocument();
if (pWnd == this && pDoc->m_rectTracker.SetCursor(this, nHitTest))
return TRUE;
return CView::OnSetCursor(pWnd, nHitTest, message);
}
OnLButtonDown - 第一版)void CRectView::OnLButtonDown(UINT nFlags, CPoint point) {
CRectTracker temp;
temp.TrackRubberBand(this, point, TRUE); // TRUE 允許反向拖曳
temp.m_rect.NormalizeRect(); // 正規化座標 (左<右, 上<下)
CView::OnLButtonDown(nFlags, point);
}
關鍵點:TrackRubberBand 以右鍵釋放結束,期間不觸發 MouseMove,結果存於 temp.m_rect。
OnLButtonDown - 完整版)新增 CRectView::bDraw 控制是否繪製橢圓。
void CRectView::OnLButtonDown(UINT nFlags, CPoint point) {
int nIn = GetDocument()->m_rectTracker.HitTest(point);
if (nIn < 0) { // 點擊在追蹤矩形外部 → 框選模式
CRectTracker temp;
temp.TrackRubberBand(this, point, TRUE);
temp.m_rect.NormalizeRect();
CRectTracker interRect;
if (interRect.m_rect.IntersectRect(temp.m_rect, GetDocument()->m_rectTracker.m_rect))
bDraw = TRUE; // 有交集 → 選中物件
else
bDraw = FALSE;
Invalidate();
}
else { // 點擊在追蹤矩形內部 → 縮放/移動模式
CClientDC dc(this);
GetDocument()->m_rectTracker.Draw(&dc);
GetDocument()->m_rectTracker.Track(this, point, TRUE); // 核心:即時追蹤縮放
bDraw = TRUE;
Invalidate();
}
CView::OnLButtonDown(nFlags, point);
}
| 回傳值 | 意義 |
|---|---|
| -1 | 矩形外部 |
| 0,1,2,3 | 左上、右上、右下、左下角 (順時針) |
| 4,5,6,7 | 上、右、下、左邊緣 (順時針) |
| 8 | 內部 (非控制點) |
TrackRubberBand:框選模式,回傳選取區域Track:縮放/移動模式,內部處理滑鼠移動與重繪,無需自行處理 MouseMoveHitTest:判斷滑鼠位置,決定互動模式GetTrueRect:取得邏輯座標下的實際矩形NormalizeRect:確保 left<right, top<bottomCPoint 三角函數計算CArray<CRectTracker*>m_rect 狀態歷史Track 過程中修正座標