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

CMFCToolBar双停靠面板Tooltip异常:如何禁用或单独处理?

问题描述

我创建了两组CMFCToolBar工具栏并完成停靠,代码如下:

m_wndToolBar1 创建代码

if (!m_wndToolBar1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | CBRS_TOOLTIPS | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER |  CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || 
    !m_wndToolBar1.LoadToolBar(IDR_MAINFRAME_256))  return -1; 
m_wndToolBar1.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndToolBar1);   

m_wndToolBar2 创建代码

if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    !m_wndToolBar2.LoadToolBar(IDR_MAINFRAME_256_3D)) return -1;

m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndToolBar2);

添加了消息映射:

ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CTunnelMainFrame::OnNeedText)

以及Tooltip处理函数:

BOOL CTunnelMainFrame::OnNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
    UINT_PTR nId = pNMHDR->idFrom - 1;
    CMFCToolBarButton* pBtnToolBar = m_wndToolBar1.GetButton(nId);

    if (pBtnToolBar)
    {
        TCHAR szBuff[64];
        ::LoadString(AfxGetResourceHandle(), pBtnToolBar->m_nID, szBuff, sizeof(szBuff) / sizeof(TCHAR));
        pTTT->lpszText = szBuff;
        pTTT->hinst = AfxGetResourceHandle();
    }

    return TRUE;
}

预期仅m_wndToolBar1显示Tooltip,但实际m_wndToolBar2也显示了m_wndToolBar1的STRINGTABLE文本。需要解决两个问题:

  1. 如何禁用m_wndToolBar2的Tooltip?
  2. 如何为m_wndToolBar2设置独立的OnNeedText处理函数?
解决方案

一、禁用m_wndToolBar2的Tooltip

直接在创建m_wndToolBar2时移除CBRS_TOOLTIPS风格即可,无需修改消息映射:

修改后的m_wndToolBar2创建代码:

if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    !m_wndToolBar2.LoadToolBar(IDR_MAINFRAME_256_3D)) return -1;

m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndToolBar2);

如果需要在创建后动态禁用Tooltip,可调用:

m_wndToolBar2.SetPaneStyle(m_wndToolBar2.GetPaneStyle() & ~CBRS_TOOLTIPS);

二、为m_wndToolBar2设置独立的Tooltip处理

步骤1:为m_wndToolBar2设置唯一的Tooltip通知ID

在m_wndToolBar2创建完成后,获取其Tooltip控件并设置自定义通知ID:

// 创建m_wndToolBar2后添加
CToolTipCtrl* pToolTip2 = m_wndToolBar2.GetToolTipCtrl();
if (pToolTip2 != nullptr)
{
    pToolTip2->SetOwner(this);
    // 设置与m_wndToolBar1不同的通知ID,比如1
    pToolTip2->SetNotifyID(1);
}

步骤2:添加多组消息映射

在消息映射中分别为两个工具栏的Tooltip通知添加处理函数:

ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CTunnelMainFrame::OnNeedTextToolBar1)
ON_NOTIFY_EX(TTN_NEEDTEXT, 1, &CTunnelMainFrame::OnNeedTextToolBar2)

步骤3:编写独立的处理函数

分别为两个工具栏编写Tooltip文本加载逻辑,注意补上TOOLTIPTEXT的类型转换:

BOOL CTunnelMainFrame::OnNeedTextToolBar1(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
    TOOLTIPTEXT* pTTT = reinterpret_cast<TOOLTIPTEXT*>(pNMHDR);
    UINT_PTR nId = pNMHDR->idFrom - 1;
    CMFCToolBarButton* pBtnToolBar = m_wndToolBar1.GetButton(nId);

    if (pBtnToolBar)
    {
        TCHAR szBuff[64];
        ::LoadString(AfxGetResourceHandle(), pBtnToolBar->m_nID, szBuff, sizeof(szBuff) / sizeof(TCHAR));
        pTTT->lpszText = szBuff;
        pTTT->hinst = AfxGetResourceHandle();
    }

    return TRUE;
}

BOOL CTunnelMainFrame::OnNeedTextToolBar2(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
    TOOLTIPTEXT* pTTT = reinterpret_cast<TOOLTIPTEXT*>(pNMHDR);
    UINT_PTR nId = pNMHDR->idFrom - 1;
    CMFCToolBarButton* pBtnToolBar = m_wndToolBar2.GetButton(nId);

    if (pBtnToolBar)
    {
        // 加载m_wndToolBar2对应的STRINGTABLE文本
        TCHAR szBuff[64];
        ::LoadString(AfxGetResourceHandle(), pBtnToolBar->m_nID, szBuff, sizeof(szBuff) / sizeof(TCHAR));
        pTTT->lpszText = szBuff;
        pTTT->hinst = AfxGetResourceHandle();
    }

    return TRUE;
}

内容的提问来源于stack exchange,提问作者Kang Gilar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:10:26