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

MFC 選單 ToolTip 終極方案:CMenuTipManager 實現懸停顯示命令提示、支援主選單/系統選單/右鍵選單、智慧定位

     編輯:VC 教學

MFC 預設僅在狀態列顯示選單提示 (離視線遠、易被忽略)。本文介紹 **CMenuTipManager** 類別,僅需一行代碼接入,即可在 **滑鼠懸停選單項 1 秒後,於項目右側彈出 ToolTip 顯示命令提示字串**,支援主選單、系統選單、右鍵選單,並解決右鍵選單無 WM_MENUSELECT 通知的難題 (WM_ENTERIDLE),附帶黏性顯示優化。

效果展示

圖一:選單項右側精準彈出 ToolTip,字體/顏色模擬系統標準提示

接入方式 (極簡)

// CMainFrame 成員
CMenuTipManager m_menuTipManager;

// OnCreate 中
m_menuTipManager.Install(this); // 傳入主框架指標,內部子類化攔截訊息

核心架構:CSubclassWnd 子類化主框架攔截訊息

  • WM_MENUSELECT:用戶在選單中移動滑鼠/鍵盤導航時發送,攜帶選中項目 ID、旗標、父選單句柄。主選單/系統選單/右鍵選單統一發送。
  • WM_ENTERIDLE:程式進入閒置等待輸入狀態時發送 (選單/對話框顯示中)。關鍵參數:lParam 為當前顯示的選單/對話框視窗句柄,用於偵測右鍵選單滑鼠離開 (無 WM_MENUSELECT 通知)。

三大關鍵技術攻關

1. ToolTip 視窗實現:CPopupText (輕量級)

  • 建立隱藏視窗 (Create)、設定文字 (SetWindowText)、延遲顯示 (ShowDelayed(ms))、取消 (Cancel)。
  • 視覺模擬系統 ToolTip:字體用 SystemParametersInfo(SPI_GETNONCLIENTMETRICS) 取得選單字體;背景色用 GetSysColor(COLOR_INFOBK)。

2. 精準定位:找到選單視窗螢幕座標 + 累加項目高度

  • 無 API 直接取得選單視窗句柄 → EnumWindows 列舉頂層視窗,匹配類別名 #32768 (選單類)。
  • 靜態輔助函數 GetRunningMenuWnd() 返回當前活動選單 HWND (Z 序最上者)。
  • 取得選單 GetWindowRect → 客戶區左上角為基準 → 遍歷選單項 (需解析選單結構或近似計算) 累加高度至目標項 → 計算 ToolTip 顯示座標 (項目右側對齊)。

3. 右鍵選單離開偵測:WM_ENTERIDLE 替代缺失的 WM_MENUSELECT

void CMenuTipManager::OnEnterIdle(UINT nWhy, CWnd* pWnd)
{
    if (nWhy == MSGF_MENU) // 選單模態中
    {
        HWND hMenuWnd = (HWND)lParam; // 隨 WM_ENTERIDLE 傳入的選單視窗句柄
        HWND hWndUnderMouse = ::WindowFromPoint(GetCursorPos());
        if (hWndUnderMouse != hMenuWnd && hWndUnderMouse != m_hwndTip)
        {
            // 滑鼠已離開選單視窗 (也非 Tip 視窗本身)
            m_wndTip.Cancel(); // 隱藏提示
            m_bSticky = FALSE; // 重置黏性
        }
    }
}

黏性顯示優化 (m_bSticky)

  • 首次使用選單:ToolTip 延遲 1 秒顯示 (ShowDelayed(1000))。
  • 曾顯示過一次:m_bSticky = TRUE,後續切換項目 **立即顯示** (ShowDelayed(0)),無需等待。
  • 選單關閉/執行命令:重置 m_bSticky = FALSE。

進階擴展:禁用項目顯示「禁用原因」

MFC 字串資源格式為 "長提示\n短提示"。若需支援禁用說明,擴展為 "長提示\n短提示\n禁用說明",修改 GetResCommandPrompt 解析第三段,在 OnGetCommandPrompt 中檢查 MF_DISABLED 旗標返回禁用說明。留作讀者練習。

總結

CMenuTipManager 以 ~200 行代碼 實現了商業級選單 ToolTip 體驗:**零侵入式接入、全選單類型支援、智慧定位、右鍵選單離開偵測、黏性優化、系統視覺一致性**。源碼結構清晰,強烈建議整合至專案通用 UI 庫。

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