You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为CCheckListBox添加内容截断时的内联工具提示?

实现CCheckListBox截断项的悬停提示功能

要给MFC的CCheckListBox实现内容截断时显示完整文本提示的功能,需要通过派生自定义类+工具提示控件来实现,具体步骤如下:

1. 派生自定义CCheckListBox类

标准CCheckListBox没有自带悬停提示功能,我们需要创建一个继承自它的自定义类,比如CMyCheckListBox,用来扩展功能。

2. 集成CToolTipCtrl工具提示

在自定义类中添加CToolTipCtrl成员变量,负责显示提示文本;同时添加变量记录上一次悬停的项,避免重复更新提示。

3. 处理鼠标移动消息

通过WM_MOUSEMOVE消息检测鼠标位置,判断当前指向的列表项:

  • 获取项的文本内容
  • 计算文本的显示宽度,和列表框的可用宽度对比
  • 如果文本宽度超过列表框宽度,说明内容被截断,触发工具提示显示完整文本;否则隐藏提示

4. 实现提示文本的更新逻辑

通过TTN_NEEDTEXT通知消息,配合工具提示控件完成文本的更新和显示。

完整代码示例

自定义类头文件(MyCheckListBox.h)

#pragma once
#include <afxwin.h>

class CMyCheckListBox : public CCheckListBox
{
    DECLARE_DYNAMIC(CMyCheckListBox)
public:
    CMyCheckListBox();
    virtual ~CMyCheckListBox();

protected:
    CToolTipCtrl m_toolTip;
    int m_lastHoverItem; // 记录上一次悬停的项索引

    DECLARE_MESSAGE_MAP()
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
    virtual void PreSubclassWindow();
};

自定义类实现文件(MyCheckListBox.cpp)

#include "MyCheckListBox.h"

IMPLEMENT_DYNAMIC(CMyCheckListBox, CCheckListBox)

CMyCheckListBox::CMyCheckListBox() : m_lastHoverItem(-1)
{
}

CMyCheckListBox::~CMyCheckListBox()
{
}

BEGIN_MESSAGE_MAP(CMyCheckListBox, CCheckListBox)
    ON_WM_MOUSEMOVE()
    ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CMyCheckListBox::OnToolTipNotify)
END_MESSAGE_MAP()

void CMyCheckListBox::PreSubclassWindow()
{
    CCheckListBox::PreSubclassWindow();

    // 初始化工具提示:设置延迟时间并激活
    m_toolTip.Create(this);
    m_toolTip.SetDelayTime(TTDT_INITIAL, 500);   // 悬停500ms后显示提示
    m_toolTip.SetDelayTime(TTDT_AUTOPOP, 5000);  // 提示显示5秒后自动消失
    m_toolTip.Activate(TRUE);
}

void CMyCheckListBox::OnMouseMove(UINT nFlags, CPoint point)
{
    CCheckListBox::OnMouseMove(nFlags, point);

    // 获取鼠标所在的列表项索引
    int itemIndex = ItemFromPoint(point, FALSE);
    if (itemIndex == LB_ERR || itemIndex == m_lastHoverItem)
        return;

    m_lastHoverItem = itemIndex;

    // 获取当前项的文本
    CString itemText;
    GetText(itemIndex, itemText);
    if (itemText.IsEmpty())
    {
        m_toolTip.Hide();
        return;
    }

    // 计算文本的实际显示宽度
    CDC* pDC = GetDC();
    CFont* pOldFont = pDC->SelectObject(GetFont());
    CSize textSize = pDC->GetTextExtent(itemText);
    pDC->SelectObject(pOldFont);
    ReleaseDC(pDC);

    // 获取列表框的可用显示宽度(减去滚动条宽度)
    CRect clientRect;
    GetClientRect(clientRect);
    int listWidth = clientRect.Width();
    if (GetHorizontalExtent() > listWidth)
        listWidth -= GetSystemMetrics(SM_CXVSCROLL);

    // 判断文本是否超出显示范围,更新提示
    if (textSize.cx > listWidth)
    {
        m_toolTip.UpdateTipText(itemText, this, ID_TOOLTIP);
        m_toolTip.Pop();
        m_toolTip.Activate(TRUE);
    }
    else
    {
        m_toolTip.Hide();
    }
}

BOOL CMyCheckListBox::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
    TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR;
    if (pTTT->uFlags & TTF_IDISHWND)
    {
        UINT nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
        if (nID == ID_TOOLTIP)
        {
            *pResult = 0;
            return TRUE;
        }
    }
    return FALSE;
}

使用方法

在对话框中,将原CCheckListBox控件的关联变量类型改为CMyCheckListBox;如果是动态创建控件,直接实例化CMyCheckListBox类即可。

内容的提问来源于stack exchange,提问作者Andrew Truckle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:38:17