使用CMFCPropertyGridCtrl时,如何避免鼠标移到超长内容编辑框时弹出悬停提示?
MFC下屏蔽CMFCPropertyGridCtrl超长内容悬停提示的实现方案
首先明确提示的两类触发来源:非编辑状态下属性展示区的内置提示、编辑状态下动态生成的编辑框自带的超长文本提示,需要针对不同来源匹配对应处理方式
1. 拦截Tooltip通知,从源头阻断提示内容生成
CMFCPropertyGridCtrl的所有内置悬停提示,都是依托内部关联的Tooltip控件,通过TTN_NEEDTEXT系列通知(Unicode环境下为TTN_NEEDTEXTW)获取待展示的完整文本后弹出的。
- 操作方式:可以为CMFCPropertyGridCtrl创建派生类,在消息映射表中添加对
TTN_NEEDTEXTW通知的处理逻辑,直接将返回的提示文本置为空字符串,同时跳过框架默认的提示文本填充流程,即可让Tooltip控件拿不到有效内容,自然不会弹出提示。 - 实现示例片段:
BEGIN_MESSAGE_MAP(CMyPropGridCtrl, CMFCPropertyGridCtrl) ON_NOTIFY_EX(TTN_NEEDTEXTW, 0, OnToolNeedText) END_MESSAGE_MAP() BOOL CMyPropGridCtrl::OnToolNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult) { // 直接清空提示文本,不调用基类的默认处理 TOOLTIPTEXTW* pTTT = reinterpret_cast<TOOLTIPTEXTW*>(pNMHDR); pTTT->szText[0] = L'\0'; *pResult = 0; return TRUE; // 标记消息已处理,不再走框架默认逻辑 }
2. 禁用动态生成的编辑子控件的Tooltip能力
当属性项进入编辑状态时,CMFCPropertyGridCtrl会临时创建编辑框、下拉框等输入类子控件,这些子控件默认会自带文本超长时的悬停提示,仅拦截属性主控件的通知无法覆盖这类场景。
- 操作方式:重写控件的
OnEdit虚函数(该函数会在属性进入编辑状态时被触发),获取当前激活的编辑类子窗口指针,直接将其关联的Tooltip对象置空,同时发送禁用提示的消息:void CMyPropGridCtrl::OnEdit(CMFCPropertyGridProperty* pProp) { // 先调用基类逻辑完成编辑控件的创建 CMFCPropertyGridCtrl::OnEdit(pProp); // 获取当前编辑状态下的活动子窗口 CWnd* pEdit = GetActiveWindow(); if (pEdit && pEdit->GetSafeHwnd()) { // 解绑编辑控件的Tooltip pEdit->SetToolTips(NULL); // 发送消息永久禁用该控件的悬停提示 pEdit->SendMessage(TTM_ACTIVATE, FALSE, 0); } } - 注意点:因为编辑控件是动态创建销毁的,不能仅在控件初始化时做一次禁用,必须在每次进入编辑状态时重复执行上述逻辑,否则新建的编辑控件会保留默认的提示能力。
3. 全局禁用控件关联的Tooltip实例
如果不需要在这个属性网格控件上展示任何形式的提示,最省事的方式是在控件初始化完成后,直接禁用其内部关联的全局Tooltip控件:
- 操作方式:在调用
CMFCPropertyGridCtrl::Create完成控件创建后,获取内部Tooltip控件的指针,直接全局禁用其激活状态:// 控件创建完成后的初始化代码中添加 CToolTipCtrl* pTip = GetToolTips(); if (pTip) { pTip->Activate(FALSE); // 全局禁用所有关联的提示弹出 } - 注意点:如果调用
GetToolTips返回空指针,说明Tooltip控件采用懒加载逻辑、尚未被创建,可以通过重写鼠标移动消息,触发Tooltip初始化流程完成后,再执行上述禁用操作。 - 这种方式的副作用是会同时屏蔽掉该控件上所有的自定义功能提示,适合对提示无任何需求的场景。
内容的提问来源于stack exchange,提问作者wsy
相关产品推荐
相关产品推荐

