I have a class derived from CTreeCtrl
. In OnCreate()
I replace the default CToolTipCtrl
object with a custom one:
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;
}
My message handler looks like this:
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CMyTreeCtrl::OnTtnNeedText)
However I never receive a TTN_NEEDTEXT
message. I had a look with Spy++ and it also looks like this message never gets sent.
What could be the problem here?
Update
I'm not sure whether this is relevant: The CTreeCtrl
's parent window is of type CDockablePane
. Could there be some extra work needed for this to work?
I believe you still have to enable the tooltip, even though you are replacing the builtin.
Well, since that did not work for you and since no-one more expert has offered any help, here a few more suggestions from me. Although they are lame, they might get you moving again:
The code I use to do this looks like this. ( I confess I do not understand all the details, I copied it from some sample code, it worked and so I never looked at it any more. )
// Enable the standard tooltip
EnableToolTips(TRUE);
// Disable the builtin tooltip
CToolTipCtrl* pToolTipCtrl = (CToolTipCtrl*)CWnd::FromHandle((HWND)::SendMessage(m_hWnd, LVM_GETTOOLTIPS, 0, 0L));
Don't you have to override OnToolHitTest()?
(old) Resource 1
(old) Resource 2:
Most of this is obvious—like setting hwnd and uId—but some of it is less so. I set the rect member to a 2-pixel-wide, 2-pixel-high rectangle centered around the mouse location. The tooltip control uses this rectangle as the bounding rectangle of the "tool," which I want to be tiny, so moving the mouse anywhere will constitute moving outside the tool. I set TTF _ NOTBUTTON in uFlags because the tooltip is not associated with a button. This is a special MFC flag defined in afxwin.h; MFC uses it to do help for tooltips. There's another MFC-extended flag for tooltips, TTF _ ALWAYSTIP. You can use it if you want MFC to display the tip even when your window is not active. You may have noticed that so far I haven't told MFC or the tooltip or the TOOLINFO what the actual text of the tip is. That's what LPSTR _ TEXTCALLBACK is for. This special value tells the tooltip control (the internal, thread-global one that MFC uses) to call my window back to get the text. It does this by sending my window a WM _ NOTIFY message with notification code TTN _ NEEDTEXT.
I haven't tried in a CTreeCtrl but I think you should call RelayEvent for the tooltip ctrl to know when the tooltip has to be displayed. Try this:
MyTreeCtrl.h:
MyTreeCtrl.cpp:
I hope this help.
Finally! I (partially) solved it:
It looks like the CDockablePane parent window indeed caused this problem...
First I removed all the tooltip-specific code from the CTreeCtrl-derived class. Everything is done in the parent pane window.
Then I edited the parent window's
OnCreate()
method:}
Unforunately we cannot simply call
AddTool()
with less parameters because the base class will complain in the form of anASSERT
about auFlag
member if there is no tool ID set. And since we need to set the ID, we also need to set a rectangle. I created aCRect
member and set it to(0, 0, 10000, 10000)
in the CTor. I have not yet found a working way to change the tool's rect size so this is my very ugly workaround. This is also why I call this solution partial. Update: I asked a question regarding this.Finally there is the handler to get the tooltip info:
Try to specifically handle all tooltip ids:
If that doesn't work, you may have to manually call RelayEvent() from PreTranslateMessage().