Home > C++, VC++, MFC > How about tooltips for my controls on a dialog!

How about tooltips for my controls on a dialog!

Recenty a colleague of mine came up and asked if it’s possible to display tooltips for toolbar buttons and other controls without much difficulty. So I gave him the solution and also decided to post it here for anyone who doesn’t know.

When a tooltip text is to be displayed the framework sends a TTN_NEEDTEXT notification, so it’s upto the handler of the event to pass a text to the event. Add two message map entries to your dialog message map section…

BEGIN_MESSAGE_MAP(CSomeDlg, CDialog)
  ON_NOTIFY_EX_RANGE( TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText )
  ON_NOTIFY_EX_RANGE( TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText )
END_MESSAGE_MAP()

Add a function to your your CSomeDlg class…

BOOL CSomeDlg::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
{
    // OnNeedText should only be called for TTN_NEEDTEXT notifications!
    ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);     // need to handle both ANSI and UNICODE versions of the message
    TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
    TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;        

    CString strTipText;    
    UINT nID = pNMHDR->idFrom;   

    if ( pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND ) ||
         pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND ))
    {
        // idFrom is actually the HWND of the tool
        nID = ((UINT)(WORD)::GetDlgCtrlID((HWND)nID));
    }        

    if (nID != 0) // will be zero on a separator
    {
        strTipText.LoadString( nID );
    }        

    // Handle conditionally for both UNICODE and non-UNICODE apps
    #ifndef _UNICODE
        if (pNMHDR->code == TTN_NEEDTEXTA)
            lstrcpyn(pTTTA->szText, strTipText, _countof(pTTTA->szText));
        else
            _mbstowcsz(pTTTW->szText, strTipText, _countof(pTTTW->szText));
    #else
        if (pNMHDR->code == TTN_NEEDTEXTA)
            _wcstombsz(pTTTA->szText, strTipText, _countof(pTTTA->szText));
        else
            lstrcpyn(pTTTW->szText, strTipText, _countof(pTTTW->szText));
    #endif    

    *pResult = 0;       

    // Bring tooltip to front
    ::SetWindowPos( pNMHDR->hwndFrom,
                    HWND_TOP,
                    0,
                    0,
                    0,
                    0,
                    SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE );      

    return TRUE;    // message was handled
}

Now tooltips should start appearing…
Well this is not limited just to dialog’s, can be used with any window provided you have provided a string resource corresponding to your control’s id. If you are using visual studio resource editor you have the provision to enter a tooltip text. Don’t forget to call EnableTooltips().

Except for unicode handling, other stuffs are pretty straight forward, easy for you understand. Just in case you are having trouble decrypting 😉 ask me!

A similar sample can be found in MSDN… 😉

Advertisements
  1. January 28, 2008 at 9:52 am

    Yes clarke that’s true, you can safely use TTN_NEEDTEXT instead of TTN_NEEDTEXTA and TTN_NEEDTEXTW. Since all MSDN samples use both the “A” and “W” explicitly I too thought of including it.

  2. Iain Clarke
    January 28, 2008 at 9:26 am

    I’m confused why you use TTN_NEEDTEXTW & TTN_NEEDTEXTA instead of simply using TTN_NEEDTEXT and letting the preprocessor handle things?

    If you were writing a control which disappears into an opaque DLL, then I could understand – but it seems over the top here.

    Other than that, it looks like very steal^h^h^h^h^hreusable code!

    Iain.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: