摘要: 本文介绍了工具提示的原理及用法,并给出其在对话框和框架窗口中的两种不同的实现方法。
关键词: 工具提示 对话框 框架窗口 Visual C++
1.前言
工具提示是一个小的弹出窗口,在窗口中显示一行文本用以描述工具的用途或其他信息。工具提示在多数情况下是隐藏的,只有当鼠标的光标放在工具上并停留大约500毫秒时才出现在光标附近,而当用户按下鼠标或光标离开工具时又重新隐藏起来。工具提示是Windows 95提供的一个新的特性,它使程序的用户界面更为美观,使用更为方便。Visual C++ 4.0为此提供了一个控件类CToolTipCtrl,由它来管理工具提示控件。
2.工具提示的原理及编程实现
工具提示控件要显示提示文本时,会发出TTN_NEEDTEXT消息以获取该文本,因此通过处理该消息我们可以为各个不同的工具提供它们所需的提示。但是,对于基于对话框的程序(从CDialog类派生)和基于框架窗口的程序(从CFrameWnd派生),它们对TTN_NEEDTEXT消息的处理是不同的。对于从CFrameWnd派生的窗口,它具有一个缺省的消息处理方法可以自动显示与工具相联系的提示文本;而对于从CDialog派生的窗口,这一缺省消息处理器并没有被调用,因此需要我们自己提供消息处理方法来处理这个消息。下面将根据这两种不同的情况来讨论。
2.1在对话框中显示工具提示
为了在对话框中显示工具提示,可以按照以下步骤进行:
(1)调用CWnd::EnableToolTips(BOOL bEnable),传人参数为TRUE,使该窗口支持工具提示的显示。
(2)加入消息映射项如下:
ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTip)
其中,TTN_NEEDTEXT为消息名,0表示工具提示控件的标识符,它始终是0,OnToolTip为TTN_NEEDTEXT消息的处理函数名。
(3)在对话框类的声明中加入如下处理函数的原型说明:
afx_msg BOOL OnToolTip(UINT id,NMHDR *pNMHDR,LRESULT *pResult);
其中,id是发出消息的工具标识符,在本函数中不用,因为可以通过NMHDR这一结构获得。NMHDR结构包含了有关通知消息的信息,其定义如下:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
在该结构中,hwndFrom为发出消息的控件句柄,idFrom为控件标识符,code为通知消息的代码,可以通过强制类型转换将NMHDR结构转换为TOOLTIPTEXT结构,后者用于为控件提供工具提示.
pResult为指向LRESULT的一个指针,表示消息处理的结果代码,在本消息处理函数中该参数可被忽略。
(4)OnToolTip函数的具体实现。
假设按钮的标识符为IDOK,下面的代码为它提供一个工具提示。
BOOL CMyDialog::OnToolTip(UINT id,NMHDR *pNMHDR,LRESULT *pResult) { TOOLTIPTEXT *pTTT=(TOOLTIPTEXT *) pNMHDR;
UINT nID=pNMHDR-idFrom; //获得控件ID
if(pTTT-uFlags&TTF_IDISHWND) //如果idFrom实际上是窗口句柄
nID=::GetDlgCtrlID((HWND)nID); //重新获得控件ID
if(nID==NULL)
return FALSE;
switch(nID)
{ case IDOK: //如果是标识符为IDOK的按钮
pTTT-lpszText="OK"; //设置提示文本
break;
}
return TRUE;
}
2.2在框架窗口中显示工具提示
对于框架窗口,情况稍微复杂一些,需要分几种情况来讨论。
首先,在文件MainFrm.cpp中定义一个全局的工具提示对象:
CToolTipCtrl m_ToolTip;
然后,在CMainFrame::OnCreate方法中创建工具提示控件:
if(!m_ToolTip.Create(this,TTS_ALWAYSTIP))
{ TRACE0("Failed to create tool tip control");
return -1;
}
上面的风格位TTS_ALWAYSTIP表示,不论控件所属的主窗口是否活动,工具提示始终有效。
最后,在CMainFrame::PreTranslateMessage()方法中加入如下代码:
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/){
// TODO: Add your specialized code here and/or call the base class
m_ToolTip.RelayEvent(pMsg);
return CFrameWnd::PreTranslateMessage(pMsg);
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)}
这样,就可以将鼠标移动的消息传给工具提示控件,并作出相应的处理。
2.2.1为窗口标题条提供工具提示
为了给标题条提供工具提示,可以在CMainFrame::OnCreate()方法中加入如下语句:
CString title;
GetWindowText(title);
m_ToolTip.AddTool(this,(LPCTSTR)title);
这样,当鼠标移到窗口的标题条或菜单条上时,将会出现工具提示,内容是该窗口的标题。
2.2.2为工具条提供工具提示
工具条一般位于菜单条的下面,由多个小的位图按钮组成,通常作为菜单命令的快捷方式来使用,它上面的位图一般非常直观,如果和工具提示一起使用则更便于用户的使用。为工具条创建工具提示的步骤如下:
(1)用Visual C++ 4.0中的工具条编辑器创建工具条时,在每个按钮的属性对话框中分别加入状态行文本和工具按钮的提示文本。例如创建一个打开文件的工具条按钮时,在提示栏中输入Opens an existing documentOpen,那么,当鼠标放在该按钮上时,将出现“Open”的工具提示,并且在状态行中出现Opens an existing document的文字。
(2)在CMainFrame类中加入一个工具条对象:
CToolBar m_wndToolBar;
然后在CMainFrame::OnCreate方法中用如下方式创建工具条控件: if(!m_wndToolBar.Create(this,WS_VISIBLE|CBRS_FLYBY| CBRS_TOOLTIPS|CBRS_TOP)||!m_wndToolBar.LoadToolBar(IDR_TOOLB AR1))
{ TRACE0("Failed to create tool bar");
return -1;
}
2.2.3为状态条提供工具提示
状态条位于窗口的下方,它可由多个小窗格构成,分别用于显示不同的内容,如当前时间和某些功能键的状态等。为状态条创建工具提示需要用到CToolTipCtrl类的AddTool()方法和Activate()方法。
首先,创建状态条对象:
CStatusBar m_wndStatusBar;
m_wndStatusBar.Create(this);
然后,将工具条对象加入到m_ToolTip的工具列表中,并使工具提示有效:
m_ToolTip.AddTool(&m_wndStatusBar,”Status Bar”);
m_ToolTip.Activate(TRUE);
这样,当鼠标光标移动到状态条上时,就会出现“Status Bar”字样的提示。
2.2.4为对话条提供工具提示
对话条有点象工具条,因为它也是一个条型的控件,上面也可以有一些按钮,但它还可以有诸如复选框和组合框等控件;它又有点象对话框,因为它可用对话框编辑器来设计。假设对话条对应的对话框模板ID号为IDD_DIALOG1,上面加入了一个ID号为IDC_QUIT的按钮和ID号为IDC_CHECK的复选框,则为上面两个控件提供工具提示的方法如下:
(1)创建一个对话条对象:
CDialogBar dlg;
if(!dlg.Create(this,IDD_DIALOG1,CBRS_TOP|CBRS_FLYBY|CBRS_TOOL TIPS,IDD_DIALOG1))
{ TRACE0("Failed to create dialog bar");
return -1;
}
(2)在字符串表中加入如下两项:
ID
Caption
IDC_QUIT
Quit the programQuit
IDC_CHECK
Check or uncheckCheck
这样,当鼠标的光标移动到上述两个控件时,将显示“Quit”和“Check”的提示.
2.2.5为窗口客户区提供工具提示
工具提示控件还可以为窗口的客户区提供工具提示,本文将使之具有如下功能:当鼠标光标在客户区移动时,在光标附近显示当前光标的客户区坐标。具体方法如下:
因为光标移动时发出WM_MOUSEMOVE消息,所以应当在OnMouseMove()方法中为客户区加入工具提示。
// 在文件MyView.cpp中
extern CToolTipCtrl m_ToolTip; //因为m_ToolTip已在MainFrm.cpp中定义
void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
static int i=0;
CString str;
str.Format(" %d,%d",point.x,point.y);
if(i==0) {
m_ToolTip.AddTool(this,(LPCTSTR)str); //将客户区加入工具列表
i=1;
}
else
m_ToolTip.UpdateTipText((LPCTSTR)str,this); //更新坐标的显示
m_Tool.Activate(TRUE);
CView::OnMouseMove(nFlags, point);
}
3.小结
基于工具提示的编程是一项引人入胜的内容,本文只介绍了一些常用的编程方法。另外,当窗口最小化时,如果最小化窗口无法容纳窗口标题,也会自动出现工具提示;在任务条的通知区域也可以插入用户自定义的图标和相应的工具提示,这可以通过调用Win32 API函数::Shell_NotifyIcon()来实现,详细情况请参见Visual C++的联机文档。