The information in this article applies to:
- The Microsoft Foundation Classes (MFC) included with:
- Microsoft Visual C++, 32-bit Edition, versions 2.1, 2.2, 4.0, 4.1,
4.2, 4.2b, 5.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:
- Use the Appwizard in Visual C++ to generate an MFC application, call it
Tooltips, and use all the Appwizard default settings.
- Include the <afxcmn.h> header file in the stdafx.h file.
- 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;
//...
};
- Initiate the two variables in the application's constructor to NULL:
CTooltipsApp::CTooltipsApp()
{
m_hwndDialog = NULL;
m_gpToolTip = NULL;
}
- 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);
}
- 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;
//...
};
- 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;
}
- 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);
}
- 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
}
- 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;
}
- Rebuild the application and bring up the About dialog box, you will see
the tooltips.
|