HOWTO: Add Tooltips for Controls on an MFC Modal Dialog Box

ID: Q135873


The information in this article applies to:
  • The Microsoft Foundation Classes (MFC), included with:
    • Microsoft Visual C++, 32-bit Editions, versions 2.1, 2.2, 4.0, 4.1, 4.2, 4.2b, 5.0, 6.0


SUMMARY

To make the CToolTipCtrl class work correctly, you must call the CToolTipCtrl::RelayEvent() function. This makes it possible for the mouse messages to be passed to the tooltip control.

For a non-modal dialog box window in an MFC application, use the window's CWnd::PreTranslateMessage() function to call CToolTipsCtrl::RelayEvent(). However, for a modal dialog box, the CDialog::PreTranslateMessage() function is not called because modal dialog boxes have their own message loops. Therefore, to use CToolTipCtrl in a modal dialog box, you need a different approach. This article gives a step-by-step example that shows how to use the CToolTipCtrl class in a MFC modal dialog box, it involves adding two additional member variables to the application class and overwriting the CWinApp::ProcessMessageFilter() function for the application class.


MORE INFORMATION

Step-by-Step Example

The following procedure generates a default MFC skeleton application and adds tooltips to the OK button on the About dialog box and the dialog box itself:

  1. Use the Appwizard in Visual C++ to generate an MFC application, call it Tooltips, and use all the Appwizard default settings.


  2. Include the <afxcmn.h> header file in the stdafx.h file.


  3. Add the following member variables to the CTooktipsApp class in the Tooltips.h file:
    
       class CTooltipsApp : public CWinApp
       {
          //...
       public:
          HWND    m_hwndDialog;
          CToolTipCtrl*   m_gpToolTip;
    
          //...
       }; 


  4. Initiate the two variables in the application's constructor to NULL:
    
       CTooltipsApp::CTooltipsApp()
       {
          m_hwndDialog = NULL;
          m_gpToolTip = NULL;
       } 


  5. Overwrite the CTooltipsApp:: ProcessMessageFilter() function as follows:
    
       BOOL CTooltipsApp::ProcessMessageFilter(int code, LPMSG lpMsg)
       {
          if (m_hwndDialog != NULL)
              if (lpMsg->hwnd == m_hwndDialog ||
                  ::IsChild(m_hwndDialog, lpMsg->hwnd))
                {
                               if (NULL != m_gpToolTip)
                                       m_gpToolTip->RelayEvent(lpMsg);
                }
               return CWinApp::ProcessMessageFilter(code, lpMsg);
       } 


  6. Use Classwizard to add a member variable for the OK button in the CAboutDlg class, and call it m_btOK. Also, add a m_pTooltip pointer to a CToolTipCtrl object:
    
       class CAboutDlg : public CDialog
       {
       public:
          CAboutDlg();
    
       // Dialog Data
          //{{AFX_DATA(CAboutDlg)
          enum { IDD = IDD_ABOUTBOX };
          CButton   m_btOK;
          //}}AFX_DATA
    
          CToolTipCtrl* m_pTooltip;
    
          //...
       }; 


  7. Add code to the CAboutDlg class' constructor and destructor to initialize and release the tooltip object, you might also need to add a default destructor first:
    
       CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
       {
          m_pTooltip = NULL;
       }
    
       CAboutDlg::~CAboutDlg()
       {
          delete m_pTooltip;
       } 


  8. Overwrite the OnMouseMove() function of the CAboutDlg class to set up the tooltip control:
    
       void CAboutDlg::OnMouseMove(UINT nFlags, CPoint point)
       {
           //Set up the tooltip
           if (!m_pTooltip)
           {
              int rt;
               m_pTooltip = new CToolTipCtrl;
             rt = m_pTooltip->Create(this);
             ASSERT(rt!=0);
    
             ((CTooltipsApp*)AfxGetApp())->m_gpToolTip= m_pTooltip;
    
             rt = m_pTooltip->AddTool(this, "About Box");
             ASSERT(rt!=0);
             rt = m_pTooltip->AddTool(&amp;m_btOK,"OK Button");
             ASSERT(rt!=0);
    
              m_pTooltip->Activate(TRUE);
           }
    
          CDialog::OnMouseMove(nFlags, point);
       } 


  9. Overwrite the OnInitDialog() function of the CAboutDlg class to pass the dialog's handle to the application:
    
       BOOL CAboutDlg::OnInitDialog()
       {
          CDialog::OnInitDialog();
    
          ((CTooltipsApp*)AfxGetApp())->m_hwndDialog=m_hWnd;
    
          return TRUE;  // return TRUE unless you set the focus to a control
                        // EXCEPTION: OCX Property Pages should return FALSE
       } 


  10. Overwrite the PostNcDestroy() function of the CAboutDlg class to reset the variables in the application class:
    
       void CAboutDlg::PostNcDestroy( )
       {
          CDialog::PostNcDestroy();
    
          ((CTooltipsApp*)AfxGetApp())->m_hwndDialog= NULL;
          ((CTooltipsApp*)AfxGetApp())->m_gpToolTip= NULL;
       } 


  11. Rebuild the application and bring up the About dialog box, you will see the tooltips.


Keywords : kbprg kbMFC KbUIDesign kbVC kbVC210 kbVC220 kbVC400 kbVC410 kbVC420 kbVC500 kbVC600 kbfaq
Version : 2.1 2.2 4.0 4.1 4.2 4.2b 5.0 6.0
Platform : NT WINDOWS
Issue type : kbhowto


Last Reviewed: January 12, 2000
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.