Q135873: HOWTO: Add Tooltips for Controls on an MFC Modal Dialog Box
Article: Q135873
Product(s): Microsoft C Compiler
Version(s): 2.1,2.2,4.0,4.1,4.2,4.2b,5.0,6.0
Operating System(s):
Keyword(s): kbCmnCtrls kbCtrl kbDlg kbMFC kbToolTip KbUIDesign kbVC210 kbVC220 kbVC400 kbVC500 kbVC
Last Modified: 15-MAY-2002
-------------------------------------------------------------------------------
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), used with:
- Microsoft Visual C++, 32-bit Editions, versions 2.1, 2.2, 4.0, 4.1
- Microsoft Visual C++, 32-bit Enterprise Edition, versions 4.2, 4.2b, 5.0, 6.0
- Microsoft Visual C++, 32-bit Professional Edition, versions 4.2, 4.2b, 5.0, 6.0
- Microsoft Visual C++, 32-bit Learning Edition, version 6.0
- Microsoft Visual C++.NET (2002)
-------------------------------------------------------------------------------
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.
NOTE: Do not do this step for Visual C++ .NET.
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:
NOTE: For Visual C++ .NET you can add a memeber variable using the "Class
View" right. (Click the AboutDialog calls, and then on Add menu, select Add
Variable.)
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(&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.
Additional query words:
======================================================================
Keywords : kbCmnCtrls kbCtrl kbDlg kbMFC kbToolTip KbUIDesign kbVC210 kbVC220 kbVC400 kbVC500 kbVC600 kbFAQ kbGrpDSMFCATL
Technology : kbAudDeveloper kbMFC
Version : :2.1,2.2,4.0,4.1,4.2,4.2b,5.0,6.0
Issue type : kbhowto
=============================================================================
THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.
Copyright Microsoft Corporation 1986-2002.