在 OnLButtonDown 中呼叫 TrackRubberBand() 繪製選框,但滑鼠釋放時 OnLButtonUp 完全不觸發。原因:TrackRubberBand 內部訊息迴圈以 WM_LBUTTONUP 作為結束條件,直接吞噬該訊息。
void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point) {
CRectTracker tracker;
tracker.TrackRubberBand(this, point, TRUE);
tracker.m_rect.NormalizeRect();
// 關鍵:TrackRubberBand 返回後,手動發送 WM_LBUTTONUP 給自己
SendMessage(WM_LBUTTONUP, 0, 0);
CDialog::OnLButtonDown(nFlags, point);
}
BOOL CMyDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT msg) {
if (pWnd == this && m_tracker.SetCursor(this, nHitTest))
return TRUE;
return CDialog::OnSetCursor(pWnd, nHitTest, msg);
}
void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point) {
Invalidate(TRUE);
if (m_tracker.HitTest(point) < 0) { // 點擊空白處:建立新選框
m_bTracking = TRUE;
CRectTracker tmp;
tmp.TrackRubberBand(this, point, TRUE);
tmp.m_rect.NormalizeRect();
m_ptStart = point;
GetCursorPos(&m_ptEnd);
SendMessage(WM_LBUTTONUP, 0, 0); // 觸發 Up 邏輯
} else { // 點擊現有選框:調整大小/位置
m_tracker.Track(this, point, TRUE);
m_tracker.m_rect.NormalizeRect();
OnPaint();
}
CDialog::OnLButtonDown(nFlags, point);
}
void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point) {
if (m_bTracking) {
ScreenToClient(&m_ptEnd);
m_tracker.m_rect.SetRect(m_ptStart.x, m_ptStart.y,
m_ptEnd.x, m_ptEnd.y);
m_tracker.m_rect.NormalizeRect();
OnPaint();
m_bTracking = FALSE;
}
CDialog::OnLButtonUp(nFlags, point);
}
TrackRubberBand 內部 GetMessage 迴圈捕獲 WM_LBUTTONUP 後直接 break,不派發給視窗程序。補發一個同樣參數的 WM_LBUTTONUP 讓訊息機制正常流轉,OnLButtonUp 即可正常執行。