方法1:通过CWnd类提供的函数来实现工具提示
1、使能工具提示
在类的PreSubclassWindow()中,调用EnableToolTips(TRUE)使一个窗口可以显示工具提示。
实现代码如下:
void CXXXCtrl::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
EnableToolTips(TRUE);
COleControl::PreSubclassWindow();
}
2、重载虚函数OnToolHitTest()
MFC调用函数来确定在某个点是否应该显示工具提示:当OnToolHitTest返回-1时,不显示工具提示;当OnToolHitTest返回其他值时,显示工具提示,并且当前调用OnToolHitTest的返回值与上次调用OnToolHitTest的返回值不一样时,工具提示窗口会被刷新。因为鼠标的每次移动都会调用此函数,所以该函数包含太多的处理并不是个好主意!
下面的代码是加到类声明中:
//{{AFX_VIRTUAL(CXXXCtrl)
public:
……
virtual int OnToolHitTest(CPoint point, TOOLINFO *pTI) const;
//}}AFX_VIRTUAL
int CXXXCtrl::OnToolHitTest(CPoint point, TOOLINFO *pTI) const
{
/* 假设CRect ToolRect是需要工具提示的区域 */
if (ToolRect.PtInRect(point))
{
pTI->hwnd = m_hWnd;
pTI->uId = (UINT)point.x;
pTI->lpszText = LPSTR_TEXTCALLBACK;
pTI->rect = ToolRect;
/* */
return pTI->uId;
}
return -1;
}
3、处理TTN_NEEDTEXT消息
当工具处理控制需要知道应该显示什么信息时,会发出这条消息。由于上一步中我们给TOOLINFO的lpszText赋值为LPSTR_TEXTCALLBACK,所以我们要处理这个消息。VC的
ClassWizard并不支持这条消息被映射,所以只有我们自己加入这条消息的映射机制加入到MESSAGE_MAP中去。我们不得不处理这个消息的两个版本,TTN_NEEDTEXTA(ANSI版)和
TTN_NEEDTEXTW(UNICODE版)。消息映射的代码如下所示:
BEGIN_MESSAGE_MAP(CXXXCtrl, COleControl)
//{{AFX_MSG_MAP(CXXXCtrl)
……
ON_NOTIFY_EX(TTN_NEEDTEXTW, 0, OnToolTipNotify)
ON_NOTIFY_EX(TTN_NEEDTEXTA, 0, OnToolTipNotify)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
下面的代码是加到类声明中:
// Message maps
//{{AFX_MSG(COLPCtrl)
……
afx_msg BOOL OnToolTipNotify(UINT id, NMHDR * pNMHDR, LRESULT * pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
TTN_NEEDTEXT的消息处理函数
BOOL CXXXCtrl::OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult)
{
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
UINT nID = pNMHDR->idFrom;
// Do not process the message from built in tooltip
if( nID == (UINT)m_hWnd &&
(( pNMHDR->code == TTN_NEEDTEXTA && pTTTA->uFlags & TTF_IDISHWND ) ||
( pNMHDR->code == TTN_NEEDTEXTW && pTTTW->uFlags & TTF_IDISHWND ) ) )
return FALSE;
// Get the mouse position
const MSG* pMessage;
CPoint pt;
pMessage = GetCurrentMessage(); // get mouse pos
ASSERT ( pMessage );
pt = pMessage->pt;
ScreenToClient( &pt );
CString strTipText;
strTipText = "你想要显示的提示信息";
#ifndef _UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
lstrcpyn(pTTTA->szText, strTipText, 80);
else
_mbstowcsz(pTTTW->szText, strTipText, 80);
#else
if (pNMHDR->code == TTN_NEEDTEXTA)
_wcstombsz(pTTTA->szText, strTipText, 80);
else
lstrcpyn(pTTTW->szText, strTipText, 80);
#endif
*pResult = 0;
return TRUE; // message was handled
}
方法2:通过MFC工具提示控件CToolTipCtrl来实现
1、添加Windows公共控件头文件afxcmn.h
在项目的Stdafx.h文件中,添加以下内容:
2、添加工具提示控件
在控件类(COleControl的派生类)声明中,添加以下内容:
CToolTipCtrl m_ctrlToolTips;
void RelayEvent(UINT message, WPARAM wParam, LPARAM lParam);
3、创建工具提示控件
为控件类(COleControl的派生类)添加WM_CREATE的消息处理程序,在其中添加以下内容
if (!m_ctrlToolTips.Create(this, TTS_ALWAYSTIP))
{
MessageBox("无法创建工具提示!", NULL, MB_ICONEXCLAMATION);
}
else
{
if (!m_ctrlToolTips.AddTool(this, "MyToolTips"))
{
MessageBox("无法为控件添加工具提示", NULL, MB_ICONEXCLAMATION);
}
else
{
m_ctrlToolTips.Activate(TRUE);
}
}
4、将控件类的鼠标消息WM_MOUSEMOVE等转发给工具提示控件处理
为控件类(COleControl的派生类)添加WM_MOUSEMOVE的消息处理程序
void CXXXCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//转发给工具提示控件处理
RelayEvent(WM_MOUSEMOVE, (WPARAM)nFlags,
MAKELPARAM(LOWORD(point.x), LOWORD(point.y)));
COleControl::OnMouseMove(nFlags, point);
}
void CXXXCtrl::RelayEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
if (NULL != m_ctrlToolTips.m_hWnd)
{
MSG Msg;
Msg.hwnd= m_hWnd;
Msg.message= message;
Msg.wParam= wParam;
Msg.lParam= lParam;
Msg.time= 0;
Msg.pt.x= LOWORD (lParam);
Msg.pt.y= HIWORD (lParam);
m_ctrlToolTips.RelayEvent(&Msg);
}
}
注:工具提示信息,可以通过UpdateTipText更新;要显示工具提示的边界矩形可以通过SetToolRect更新
关于CToolTipCtrl(以下内容来自《MFC库类详解》)
CToolTipCtrl
CToolTipCtrl类封装了一个“工具提示控件”的性能。工具提示控件是一个小的弹出窗口,它用来显示一行描述应用程序中的一个工具的目的的文本。一个“工具”可以是一个窗口,比如说一个子窗口或控件,或者是一个窗口的客户区中的一个应用程序定义的矩形区域。一个工具提示大多数时间是隐藏的,只有在用户将光标放在一个工具上并停留大约半秒时间时,工具提示才显示出来。工具提示显示在光标的附近,当用户点击鼠标按钮或将光标从工具上离开时,工具提示消失。
CToolTipCtrl提供了一些功能,用来控制工具提示的初始时间和持续时间,工具提示周围的边距宽度,工具提示窗口本身的宽度,以及工具提示的背景和文本颜色。一个工具提示控件可以为多个工具提供信息。
CToolTipCtrl类提供了Windows通用工具提示控件的功能。这个控件(也就是这个CToolTipCtrl类)只对运行在Windows
95和Windows NT 3.51或更高版本下的程序来说是可用的。
有关使能CToolTipCtrl的更多信息,参见“Visual
C++程序员指南”中的“控件主题”和“使用CToolTipCtrl”。
#include
请参阅:
CToolTipCtrl类成员
构造
| 创建一个CToolTipCtrl对象
|
| 创建一个工具提示控件并将它与一个CToolTipCtrl对象连接 |
属性
| 获取一个工具提示控件为一个工具维持的文本
|
| 获取一个工具提示控件维持的关于一个工具的信息
|
| 设置一个工具提示控件为一个工具维持的文本
|
| 获取由一个工具提示控件支持的工具数
|
| 获取当前为一个工具提示控件设置的初始,弹出,和再显示持续时间
|
| 为一个工具提示控件设置初始,弹出,和再显示持续时间
|
| 获取当前为一个工具提示窗口设置的上,左,底,和右边距
|
| 为一个工具提示窗口设置上,左,底,和右边距
|
| 获取一个工具提示窗口的最大宽度
|
| 设置一个工具提示窗口的最大宽度
|
| 获取一个工具提示窗口中的背景颜色
|
| 设置一个工具提示窗口中的背景颜色
|
| 获取一个工具提示窗口中的文本颜色
|
| 设置一个工具提示窗口中的文本颜色 |
操作
| 激活工具提示控件或使它成为不活动的
|
| 向一个工具提示控件注册一个工具
|
| 从工具提示控件中删除一个工具
|
| 测试一个点,以确定它是否位于给定工具的边界矩形之内,如果是,返回关于这个工具的信息
|
| 传递一个鼠标消息给工具提示控件处理
|
| 为一个工具设置一个新的边界矩形
|
| 为一个工具设置工具提示文本
|
| 强制当前工具被重画
|
| 从视中删除一个被显示的工具提示窗口 |