Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tool tips for custom made control using CToolTipCtrl ? (MFC)

Tags:

c++

mfc

I made a custom control derived from CWnd (a line chart) and I'm wondering if I can use CToolTipCtrl for displaying tool tips for points on the graph. If yes, how could I do that?

Btw, when I move my mouse over the point, the rectangle containg string with information about values of the point, should pop up.

like image 741
dragan.stepanovic Avatar asked Jun 11 '26 02:06

dragan.stepanovic


2 Answers

Yes, this works, actually I do this exact same thing, also in a line graph chart, however there are a few drawbacks/remarks. The message handling is a bit wonky, with some messages not being send according to the documentation, and some workarounds being necessary to keep the control self-contained (not requiring help from the parent to reflect notifications).

What you do is declare a variable in your CWnd-derived class

CToolTipCtrl m_ToolTipCtrl;
CString m_ToolTipContent;

Then do this on OnCreate:

m_ToolTipCtrl.Create(this, TTS_ALWAYSTIP);
m_ToolTipCtrl.Activate(TRUE);

Optionally, you can also set the delay time:

m_ToolTipCtrl.SetDelayTime(TTDT_AUTOPOP, -1);
m_ToolTipCtrl.SetDelayTime(TTDT_INITIAL, 0);
m_ToolTipCtrl.SetDelayTime(TTDT_RESHOW, 0);

When you want to show your tooltip (presumably in OnMouseMove()), use

m_ToolTipCtrl.Pop();

BUT this only works in UNICODE builds. So if you're still on MBCS (like I am), you can only show the tooltip after a certain delay. Use this to set your tooltip text (also in OnMouseMove):

// Not using CToolTipCtrl::AddTool() because
// it redirects the messages to the parent
TOOLINFO ti = {0};
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_IDISHWND;    // Indicate that uId is handle to a control
ti.uId = (UINT_PTR)m_hWnd;   // Handle to the control
ti.hwnd = m_hWnd;            // Handle to window
// to receive the tooltip-messages
ti.hinst = ::AfxGetInstanceHandle();
ti.lpszText = LPSTR_TEXTCALLBACK;
ti.rect = <rectangle where, when the mouse is over it, the tooltip should be shown>;
m_ToolTipCtrl.SendMessage(TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
m_ToolTipCtrl.Activate(TRUE);

m_ToolTipContent = "my tooltip content";

Furthermore, you need to handle TTNNeedText:

// The build-agnostic one doesn't work for some reason.
ON_NOTIFY_EX(TTN_NEEDTEXTA, 0, OnTTNNeedText)
ON_NOTIFY_EX(TTN_NEEDTEXTW, 0, OnTTNNeedText)

BOOL GraphCtrlOnTTNNeedText(UINT id, NMHDR* pTTTStruct,  LRESULT* pResult)
{
    TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pTTTStruct;
    //pTTT->lpszText = "some test text";
    //pTTT->lpszText = m_ToolTipContent;
    strncpy_s(pTTT->lpszText, 80, m_ToolTipContent, _TRUNCATE);

    return TRUE;
}

You'll have to modify this a bit, and read the documentation of the functions and messages, to get this to work in your project but yes it can be done.

like image 129
Roel Avatar answered Jun 12 '26 15:06

Roel


For those that may still be looking for an answer to this as I was. (I couldn't get the one above to work - Things in MFC may have changed.)

All code is contained within the custom control class.

In your class definition add:

CToolTipCtrl ToolTip;

In PreSubclassWindow() add:

#define TOOLTIP_ID 1
ToolTip.Create(this, TTS_ALWAYSTIP );

CRect rc;
GetClientRect(rc);
ToolTip.AddTool(this, "Tool tip text", rc, TOOLTIP_ID);

In PreTranslateMessage() add:

ToolTip.RelayEvent(msg);

Whenever your tool tip text changes add:

ToolTip.UpdateTipText("New Tip Text", this, TOOLTIP_ID);
like image 36
Sean Hawkins Avatar answered Jun 12 '26 14:06

Sean Hawkins



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!