How to display tooltips for a toolbar in a dialog

 

It is relatively easy to place a toolbar in a dialog box, but I had a hard time making the tooltips appear since none of the TTN_xxxx message handlers are present in a CDialog derived class. This article describes a simple technique for getting tooltips when you have a toolbar in a dialog. It also gives a brief overview of the steps involved in adding a toolbar to a dialog box.

Step 1

In the dialog's header file you must add a CToolBar instance and an entry in the message map to handle the tooltip messages.

protected:

     CToolBar cToolBar;

at the bottom of the wizard generated message map entries add:

//}}AFX_MSG

afx_msg BOOL OnToolTipText(UINT nID, NMHDR* pNMHDR, LRESULT* pResult);

DECLARE_MESSAGE_MAP()

Step 2

In dialog's implementation file add the following to the end of OnInitDialog to show the toolbar.

//add the tool bar to the dialog

cToolBar.Create(this);

cToolBar.LoadToolBar(IDR_TOOLBAR);

cToolBar.ShowWindow(SW_SHOW);

cToolBar.SetBarStyle(CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY);

RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

At the bottom of the message map add the following:

FX_MSG_MAP

ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)

ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)

END_MESSAGE_MAP()

Finally add the message handler method as entered in the message map:

BOOL CToolBarTipTestDialog::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)

{

     ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);

     // if there is a top level routing frame then let it handle the message

     if (GetRoutingFrame() != NULL) return FALSE;

     // to be thorough we will need to handle UNICODE versions of the message also !!

     TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;

     TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;

     TCHAR szFullText[512];

     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 = ::GetDlgCtrlID((HWND)nID);

     }

     if (nID != 0) // will be zero on a separator

     {

          AfxLoadString(nID, szFullText);

          strTipText=szFullText;

#ifndef _UNICODE

          if (pNMHDR->code == TTN_NEEDTEXTA)

          {

               lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText));

          }

          else

          {

               _mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText));

          }

#else

          if (pNMHDR->code == TTN_NEEDTEXTA)

          {

               _wcstombsz(pTTTA->szText, strTipText,sizeof(pTTTA->szText));

          }

          else

          {

               lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText));

          }

#endif

          *pResult = 0;

          // bring the tooltip window above other popup windows

          ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,SWP_NOACTIVATE|

               SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); return TRUE;

     }