首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC 程式設計中 WM_MOUSEENTER 與 WM_MOUSELEAVE 訊息處理全攻略

     編輯:關於VC++

WM_MOUSEENTER / WM_MOUSELEAVE (實為 WM_MOUSEHOVER/WM_MOUSELEAVE) 雖有定義且看似實用,但預設不會自動發送,需在 WM_MOUSEMOVE 中手動啟動追蹤。

必要成員變數

BOOL m_bTracking = FALSE;  // 追蹤狀態旗標

訊息對應表項

ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)

處理函數宣告

afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);

核心實作:WM_MOUSEMOVE 中啟動追蹤

void CDemo::OnMouseMove(UINT nFlags, CPoint point) {
    if (!m_bTracking) {
        TRACKMOUSEEVENT tme;
        tme.cbSize = sizeof(tme);
        tme.hwndTrack = m_hWnd;
        tme.dwFlags = TME_LEAVE | TME_HOVER;  // 同時啟用離開與停留
        tme.dwHoverTime = 1;                  // 停留判定時間(毫秒),1 為預設系統值
        m_bTracking = _TrackMouseEvent(&tme); // 成功返回 TRUE
    }
    // 其他滑鼠移動邏輯...
}

LRESULT CDemo::OnMouseLeave(WPARAM wParam, LPARAM lParam) {
    m_bTracking = FALSE;  // 重置旗標,下次進入再啟動
    // 滑鼠離開視窗客戶區處理邏輯
    return 0;
}

LRESULT CDemo::OnMouseHover(WPARAM wParam, LPARAM lParam) {
    // 滑鼠在視窗停留超過 dwHoverTime 處理邏輯
    return 0;
}

關鍵機制解析

  1. 一次性觸發:_TrackMouseEvent 設定的追蹤為一次性,WM_MOUSELEAVE 或 WM_MOUSEHOVER 觸發後自動取消,需在處理函數中重置旗標,下次 WM_MOUSEMOVE 重新啟動
  2. TME_LEAVE:滑鼠離開視窗客戶區觸發 WM_MOUSELEAVE
  3. TME_HOVER:滑鼠在視窗靜止超過 dwHoverTime 觸發 WM_MOUSEHOVER
  4. TME_NONCLIENT:擴展至非客戶區(標題列、邊框等)

常見應用場景

  • 按鈕/工具列熱追蹤效果(扁平化按鈕滑鼠進入高亮)
  • ToolTip 延遲顯示控制
  • 自訂控制項滑鼠進入/離開狀態切換
  • 拖放操作視覺回饋

注意事項

  • 若視窗被遮擋或最小化,不會收到 WM_MOUSELEAVE,依賴系統自動重置
  • 多視窗嵌套時,子視窗接收自身區域訊息
  • dwHoverTime = HOVER_DEFAULT (0xFFFFFFFF) 使用系統預設值(通常 400ms)
  • MFC CWnd::TrackMouseLeave 封裝了此邏輯,可簡化實作
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved