我怎么定义显示提示在一个CTreeCtrl?
-
06-07-2019 - |
题
我有一个类源自 CTreeCtrl
.在 OnCreate()
我取代默认 CToolTipCtrl
对象与一个自定义:
int CMyTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
// Replace tool tip with our own which will
// ask us for the text to display with a TTN_NEEDTEXT message
CTooltipManager::CreateToolTip(m_pToolTip, this, AFX_TOOLTIP_TYPE_DEFAULT);
m_pToolTip->AddTool(this, LPSTR_TEXTCALLBACK);
SetToolTips(m_pToolTip);
// Update: Added these two lines, which don't help either
m_pToolTip->Activate(TRUE);
EnableToolTips(TRUE);
return 0;
}
我的消息处理程序是这样的:
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CMyTreeCtrl::OnTtnNeedText)
但是我永远不会收到 TTN_NEEDTEXT
信息。我有一个看起来与间谍++它看起来也像这样的消息永远不会被发送。
可能是什么问题吗?
更新
我不确定这是否是相关的:的 CTreeCtrl
's父窗口的类型 CDockablePane
.可能有一些额外的工作需要对这一工作?
解决方案
最后!我(部分)解决了它:
看起来CDockablePane父窗口确实导致了这个问题......
首先,我从CTreeCtrl派生类中删除了所有特定于工具提示的代码。一切都在父窗格窗口中完成。
然后我编辑了父窗口的 OnCreate()
方法:
int CMyPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDockablePane::OnCreate(lpCreateStruct) == -1)
return -1;
const DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
TVS_CHECKBOXES | TVS_DISABLEDRAGDROP | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
TVS_INFOTIP | TVS_NOHSCROLL | TVS_SHOWSELALWAYS;
// TREECTRL_ID is a custom member constant, set to 1
if(!m_tree.Create(dwStyle, m_treeRect, this, TREECTRL_ID ) )
{
TRACE0("Failed to create trace tree list control.\n");
return -1;
}
// m_pToolTip is a protected member of CDockablePane
m_pToolTip->AddTool(&m_tree, LPSTR_TEXTCALLBACK, &m_treeRect, TREECTRL_ID);
m_tree.SetToolTips(m_pToolTip);
return 0;
}
不幸的是,我们不能简单地用较少的参数调用 AddTool()
,因为基类会以 ASSERT
的形式抱怨 uFlag
如果没有设置工具ID,则为member。
由于我们需要设置ID,我们还需要设置一个矩形。我创建了一个 CRect
成员并将其设置为CTor中的(0,0,10000,10000)
。我还没有找到一种改变工具的矩形大小的工作方式,所以这是我非常难看的解决方法。这也是我将此解决方案称为部分原因的原因。 更新:我问了一个有关此事的问题。一> 强>
最后有一个获取工具提示信息的处理程序:
// Message map entry
ON_NOTIFY(TVN_GETINFOTIP, TREECTRL_ID, &CMobileCatalogPane::OnTvnGetInfoTip)
// Handler
void CMyPane::OnTvnGetInfoTip(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTVGETINFOTIP pGetInfoTip = reinterpret_cast<LPNMTVGETINFOTIP>(pNMHDR);
// This is a CString member
m_toolTipText.ReleaseBuffer();
m_toolTipText.Empty();
// Set your text here...
pGetInfoTip->pszText = m_toolTipText.GetBuffer();
*pResult = 0;
}
其他提示
我相信你还是要使该工具提示,即使你更换的系统.
EnableToolTips(TRUE);
好吧,既然这并没有为你工作和由于没有一个人更多的专家具有提供任何帮助,这里的一些更多的建议。虽然他们是跛脚的,他们可能会让你动再次:
- 确保你的OnCreate()常规训实际上是正在执行。
- 启用的工具提前更换。
代码是我用来做这个看起来是这样的。(我承认我不明白所有的细节,我复制了它从一些样本编码,它的工作和所以我从没看过它的任何更多。)
//启用的标准提示
EnableToolTips(TRUE);
//禁止的内置的提示
CToolTipCtrl*pToolTipCtrl=(CToolTipCtrl*)CWnd::FromHandle((HWND)::图(m_hWnd,LVM_GETTOOLTIPS,0,0L));
我没有在CTreeCtrl中尝试过,但我认为应该使用工具提示ctrl调用RelayEvent来了解何时必须显示工具提示。试试这个:
MyTreeCtrl.h:
virtual BOOL PreTranslateMessage(MSG* pMsg);
MyTreeCtrl.cpp:
BOOL CMyTreeCtrl::PreTranslateMessage(MSG* pMsg)
{
m_pToolTip.Activate(TRUE);
m_pToolTip.RelayEvent(pMsg);
return CTreeCtrl::PreTranslateMessage(pMsg);
}
我希望这有帮助。
您是否必须覆盖OnToolHitTest()?
除了返回命中代码(nHit)之外,还必须填写TOOLINFO结构。以下是VIRGIL在CMainFrame :: OnToolHitTest中的表现:
int nHit = MAKELONG(pt.x, pt.y);
pTI->hwnd = m _ hWnd;
pTI->uId = nHit;
pTI->rect = CRect(CPoint(pt.x-1,pt.y-1),CSize(2,2));
pTI->uFlags |= TTF _ NOTBUTTON;
pTI->lpszText = LPSTR _ TEXTCALLBACK;
大部分内容都很明显&#8212;就像设置hwnd和uId&#8212;但其中一些不那么重要。我将rect成员设置为以鼠标位置为中心的2像素宽,2像素高的矩形。工具提示控件使用该矩形作为“工具”的边界矩形。我希望它很小,所以将鼠标移动到任何地方都会构成移动到工具之外。我在uFlags中设置了TTF _ NOTBUTTON,因为工具提示与按钮没有关联。这是afxwin.h中定义的特殊MFC标志; MFC使用它来为工具提示提供帮助。还有另一个MFC扩展的工具提示标志,TTF _ ALWAYSTIP。如果您希望MFC显示提示,即使您的窗口未处于活动状态,也可以使用它。 您可能已经注意到,到目前为止,我还没有告诉MFC或工具提示或TOOLINFO提示的实际文本是什么。这就是LPSTR _ TEXTCALLBACK的用途。这个特殊值告诉工具提示控件(MFC使用的内部,线程全局的控件)调用我的窗口来获取文本。它通过向我的窗口发送带有通知代码TTN _ NEEDTEXT的WM _ NOTIFY消息来完成此操作。
尝试专门处理所有工具提示ID:
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, &CMyTreeCtrl::OnNeedTipText)
如果这不起作用,您可能必须从PreTranslateMessage()手动调用RelayEvent()。