CSliderCtrl 內建 Tooltip 僅顯示當前位置整數值。若需顯示「總共 500 幀,目前第 13 幀」或浮點數值,必須自行實作。本文示範用 CToolTipCtrl 攔截 TTN_NEEDTEXT 訊息實現完全自訂 Tooltip。
// 對話框類別
CSliderCtrl m_Slider; // IDC_SLIDERTEST
CToolTipCtrl m_ToolTip; // 自訂 Tooltip 控件
// 訊息映射
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipNotify)
// OnInitDialog
m_Slider.SetRange(0, 500, TRUE);
m_Slider.SetPos(0);
// 建立 Tooltip,關聯 Slider 控件
m_ToolTip.Create(GetDlgItem(IDC_SLIDERTEST));
m_ToolTip.Activate(TRUE);
void CMyDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar == (CScrollBar*)GetDlgItem(IDC_SLIDERTEST)) {
m_ToolTip.Update(); // 觸發 TTN_NEEDTEXT
}
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
BOOL CMyDialog::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR;
UINT nID = pNMHDR->idFrom;
// idFrom 可能是 HWND,需轉換為控件 ID
if (pTTT->uFlags & TTF_IDISHWND) {
nID = ::GetDlgCtrlID((HWND)nID);
}
if (nID == IDC_SLIDERTEST) {
// 這裡自訂 Tooltip 文字內容
CString strTip;
strTip.Format(_T("總共 500 幀,目前第 %d 幀"), m_Slider.GetPos());
// 複製到 TOOLTIPTEXT 結構
_tcscpy(pTTT->lpszText, strTip);
pTTT->hinst = NULL; // 不使用資源字串
return TRUE; // 表示已處理
}
return FALSE; // 其他控件用預設處理
}
typedef struct tagTOOLTIPTEXT {
NMHDR hdr; // 標準通知頭 (hwndFrom, idFrom, code)
LPTSTR lpszText; // Tooltip 文字緩衝區 (最大 80 字元)
char szText[80]; // ANSI 版本緩衝區
HINSTANCE hinst; // 若使用資源字串,此為模組句柄
UINT uFlags; // TTF_IDISHWND 等旗標
} TOOLTIPTEXT, *PTOOLTIPTEXT;
同樣邏輯可用於任何控件:
只需在 OnToolTipNotify 中判斷 nID 並回傳對應文字。
lpszText 緩衝區僅 80 字元,長字串會被截斷,需自行控制長度。TTN_NEEDTEXT 在 Tooltip 即將顯示前發送,頻率較高,處理函數務必輕量。_tcscpy/CString 自動適配。攔截 TTN_NEEDTEXT 是實現完全自訂 Tooltip 的標準做法。幾行程式碼即可讓 Slider 顯示豐富資訊,同樣技巧可擴充至所有控件,大幅提升使用者體驗。