ToolTip在VC中的使用

ToolTip在VC中的使用

(2010-01-21 14:13:40)
标签:

tooltip

vc

使用

it

分类:VC
[转]ToolTip在VC中的使用
 

按照下面的步骤去做:
1、先为static设置一个ID,如ID_TIP;
2、在CDialogBar的头文件中的AFX_MSG内加入一行申明
afx_msg BOOL OnToolTip(UINT id,NMHDR * pNMHDR,LRESULT * pResult);
3、在CDialogBar的CPP文件中的AFX_MSG_MAP内加入一行
ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTip)
4、在CDialogBar的CPP文件中的OnInitDialog()函数内加入
EnableToolTips(TRUE);
5、在CDialogBar的CPP文件中添加OnToolTip函数
BOOL CDialogBar::OnToolTip(UINT id,NMHDR * pNMHDR,LRESULT * pResult)
{
TOOLTIPTEXT * pTTT=(TOOLTIPTEXT *)pNMHDR;
UINT uID = pNMHDR->idFrom;
if(pTTT->uFlags & TTF_IDISHWND)
uID = ::GetDlgCtrlID((HWND)uID);
if(uID == NULL) return FALSE;
switch(uID)
{
case IDC_TIP:
pTTT->lpszText="添加你的提示内容";
break;
}
return TRUE;
}
这样就可以了。
其实,上面的方法可以为任何控件添加tip提示。

用VC实现TOOL TIP.比较复杂,其实也简单,但MFC帮助一些窗口实现,而另一些窗口又不实现,倒搞得复杂了.最开始我用WM_MOUSEMOVE消息,然后用CToolTipCtrl::Pop,这个方法太笨.不建议用.除非需要自定义.

MFC对TOOL TIP的支持不错的.缺省情况CFrameWnd支持很好.然后是CWnd.主要体现在TTN_NEEDTEXT消息的支持和OnToolHitTest的支持.TTN_NEEDTEXT是在CFrameWnd中支持的.OnToolHitTest是在CWnd中支持的.有了这些支持,可以在框架窗口中很好实现ToolBar的TIP.和在一个对话框中很好实现一个控件的TOOL TIP.

举例.在对话框中实现TOOL TIP.

1.EnableToolTips( TRUE )是不可少的.建议在:CDialog::OnInitDialog 调用吧.

2.ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnNeedText ).OnNeedText实现了TOOL TIP的文字.传入的参数idFrom是控件的ID,根据控件ID得到相应的TIP文字

就这么简单的两步,就实现了对话框中的TOOL TIP.其实不只对话框,任何窗口都可以用上面的方法实现自己的子窗口控件的TIP.但前提是必须是CWnd的派生类.

这就看出了MFC对TOOL TIP的支持很厉害

但这一切都是MFC实现的我们简单描述一下它的实现原理,这样看得更清楚

CWnd本身就带有一个CToolTipCtrl对象,是放在pThreadState中的这个不说了,知道CWnd有就行了

CWnd负责创建它,然后在PreTranslateMessage中调用了FilterToolTipMessage,这个函数的作用是处理WM_MOUSEMOVE,WM_NCMOUSEMOVE等消息,给CToolTipCtrl一个机会,判断鼠标是否在需要显示TIP的窗口上,如果是,就显示.FilterToolTipMessage先从CWnd::OnToolHitTest得到TOOLINFO:中的数据,比如哪个控件需要TIP等信息,然后利用ADDTOOL消息把这个需要TIP的控制加入到CToolTipCtrl的TOOL列表中,然后将鼠标移动的消息转给CToolTipCtrl处理.如果这个TIP的文字需要用回调函数来获得,就用WM_NOTIFY的TTN_NEEDTEXT从CToolTipCtrl的父窗口获取.这个过程就是CToolTipCtrl判断是否要显示TIP,到获得文字并显示TIP的全过程

这样一分析,就知道原来CWnd帮助实现了控件子窗口的TIP其实就是实现了OnToolHitTest这个函数,然后在PreTranslateMessage中转发消息,帮助CToolTipCtrl正确显示TIP.

而CFrameWnd是实现了TTN_NEEDTEXT的响应,帮助子窗口实现TIP.

其实我们也可以不要这些缺省实现,自己用CToolTipCtrl搞定,做法一样:

1.CToolTipCtrl::Create创建Tool Tip

2.AddTool增加一个TOOL,这里的TOOL就是需要显示TIP的一个区域或一个子窗口.如果对AddTool使用有不清楚的地方,建议查看源程序.可能会觉得直接使用TTM_ADDTOOL更方便.

3.在PreTranslateMessage中调用CToolTipCtrl::RelayMessage

4.如果在AddTool中,文字是用回调函数实现,那就要处理TTN_NEEDTEXT消息.

其实自己创建CToolTipCtrl和MFC做的一样.只是不需要在OnToolHitTest中给出需要显示TIP的窗口或者区域.

如果给子窗口用TIP.就用MFC最简单.如果给自己呢?

设置TOOLINFO中的uFlags = TTF_IDISHWND,然后设置uId为窗口句柄,hWnd为窗口句柄就可以了.

写了这么多,有不对的地方还请和我联系一下,帮助我改正错误.

只是有个问题还没搞明白.就是为什么MFC把CToolTipCtrl放在了pThreadState中.难道是为了用一个TOOL TIP为该线程的所有窗口服务吗?难道是一种节约资源的表现.这点还需要研究.如果哪位朋友知道答案,还希望能不吝赐教.谢谢

//头文件加入
CToolTipCtrl m_tooltip;
//主窗口初始化时加入
m_tooltip.Create(this);
m_tooltip.Activate(TRUE);
m_tooltip.AddTool(GetDlgItem(IDC_>name<), ">text<");
//IDC_>name<为你控件的ID,>text<为显示的内容

利用ClassWizard建立PreTranslateMessage
BOOL CTest5Dlg::PreTranslateMessage(MSG* pMsg)
{
m_tooltip.RelayEvent(pMsg); //你加入的代码
return CDialog::PreTranslateMessage(pMsg);
}

猜你喜欢

转载自blog.csdn.net/wingsing2010/article/details/5779478