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

MFC 對話框控制項 ToolTip 與狀態列提示雙重顯示:WM_SETCURSOR + TTN_NEEDTEXT 實現

     編輯:關於VC++

需求

在對話框中:
1. 滑鼠懸停控制項 → 顯示 ToolTip (黃色小方塊)
2. 同時在主框架狀態列顯示該控制項的詳細說明文字

資源字串設計

字串表 ID 與控制項 ID 一致,格式:
IDC_MYBTN = "這是按鈕的狀態列說明\nToolTip 文字"
以 \n 分隔:前段→狀態列,後段→ToolTip。

核心實現 (對話框類別)

標頭檔


class CMyDialog : public CDialog {
protected:
    void SetStatusText(UINT nID = 0);
    afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
    afx_msg BOOL OnTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
    DECLARE_MESSAGE_MAP()
};

訊息對應


BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
    ON_WM_SETCURSOR()
    ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnTipNotify)
END_MESSAGE_MAP()

OnSetCursor:滑鼠進入控制項 → 更新狀態列 + 觸發 ToolTip


BOOL CMyDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) {
    if (pWnd == this) { // 滑鼠在對話框空白處
        SetStatusText(); // 顯示預設閒置文字
    } else {
        // 構造 TTN_NEEDTEXT 訊息手動觸發 ToolTip
        TOOLTIPTEXT ttt;
        ttt.hdr.hwndFrom = m_hWnd;
        ttt.hdr.idFrom = pWnd->GetDlgCtrlID();
        ttt.hdr.code = TTN_NEEDTEXT;
        ttt.uFlags = TTF_IDISHWND;

        SetStatusText(pWnd->GetDlgCtrlID()); // 更新狀態列
        SendMessage(WM_NOTIFY, ttt.hdr.idFrom, (LPARAM)&ttt); // 觸發 ToolTip
    }
    return CDialog::OnSetCursor(pWnd, nHitTest, message);
}

SetStatusText:發送 WM_SETMESSAGESTRING 至狀態列


void CMyDialog::SetStatusText(UINT nID) {
    if (nID == 0) nID = AFX_IDS_IDLEMESSAGE; // 預設 "Ready"

    CWnd* pStatusBar = AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
    if (pStatusBar) {
        AfxGetMainWnd()->SendMessage(WM_SETMESSAGESTRING, nID);
        pStatusBar->SendMessage(WM_IDLEUPDATECMDUI);
        pStatusBar->UpdateWindow();
    }
}

OnTipNotify:解析字串資源回傳 ToolTip 文字


BOOL CMyDialog::OnTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult) {
    TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR;
    UINT nID = pNMHDR->idFrom;

    if (pTTT->uFlags & TTF_IDISHWND) {
        nID = ::GetDlgCtrlID((HWND)nID);
        if (nID) {
            TCHAR szFull[256];
            AfxLoadString(nID, szFull); // 載入完整字串
            CString strTip;
            AfxExtractSubString(strTip, szFull, 1, '\n'); // 取第二段 (ToolTip)
            if (!strTip.IsEmpty()) {
                _tcscpy(pTTT->lpszText, strTip);
                pTTT->hinst = AfxGetResourceHandle();
                return TRUE;
            }
        }
    }
    return FALSE;
}

OnDestroy 清理


void CMyDialog::OnDestroy() {
    SetStatusText(); // 還原預設狀態列文字
    CDialog::OnDestroy();
}

必要標頭


#include  // AFX_IDS_IDLEMESSAGE, AFX_IDW_STATUS_BAR
#include   // 資源相關

使用限制

  • 對話框必須為 SDI/MDI 主框架的子視窗 (非模態或 CFormView),才能存取主框架狀態列
  • 模態對話框 (DoModal) 無主框架,狀態列功能無效,但 ToolTip 仍可運作

總結

利用 WM_SETCURSOR 攔截滑鼠進入控制項瞬間,手動觸發 TTN_NEEDTEXT 並同步更新狀態列。字串資源以 \n 分隔雙重用途,零額外記憶體、零硬編碼,維護極簡單。

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