首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC 消息機制:為何應用程序輸出欄未顯示 "delete button"?

     編輯:程式設計疑難解答

現象

鼠標按下、移動、釋放時,預期輸出 "down button"、"move button"、"delete button",但實際**缺少 "delete button"**。

根因

`WM_LBUTTONUP` 消息未觸發,因為**鼠標捕獲**機制:

  • 在 `OnLButtonDown` 中調用了 `SetCapture()`,將鼠標捕獲給當前窗口。
  • 捕獲期間,**所有鼠標消息(含 UP)都發送給捕獲窗口**,即使鼠標移出客戶區。
  • 代碼中**未在 `OnLButtonUp` 調用 `ReleaseCapture()`**,導致捕獲持續,後續 `WM_LBUTTONUP` 被系統吞噬或不再發送給原窗口處理函數。

正確捕獲釋放模式

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
    SetCapture(); // 1. 捕獲鼠標
    // 記錄起始點、設置標志...
    CView::OnLButtonDown(nFlags, point);
}

void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
    if (GetCapture() == this) { // 只有捕獲期間才處理拖拽
        // 繪製橡皮筋、更新狀態...
    }
    CView::OnMouseMove(nFlags, point);
}

void CMyView::OnLButtonUp(UINT nFlags, CPoint point)
{
    if (GetCapture() == this) {
        ReleaseCapture(); // 2. **必須釋放捕獲**
        // 完成拖拽邏輯、輸出 "delete button"...
    }
    CView::OnLButtonUp(nFlags, point);
}

關鍵點

操作作用
`SetCapture()`讓窗口接收鼠標離開客戶區後的消息,實現拖拽超出邊界仍跟隨。
`ReleaseCapture()`結束捕獲,恢復正常命中測試分發。缺失會導致 UP 消息丟失、後續點擊失效。
`GetCapture() == this`防止多窗口/巢狀捕獲混亂,僅在自己捕獲時處理。

調試技巧

  • 在 `OnLButtonUp` 首行加 `TRACE(_T("Up\n"));` 觀察輸出窗口是否打印。
  • 用 Spy++ 監控 `WM_LBUTTONUP`、`WM_CAPTURECHANGED` 消息流向。

**MFC 鼠標捕獲:有借有還,`SetCapture` 必配 `ReleaseCapture`,否則消息鏈斷裂。**

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved