在CTreeView中给CtreeCtrl增加提示(tip)的功能的问题
1 新建工程
l 新建一个 MFC 工程,命名: TreeViewTipp
l 设置为 单文档 程序,注意语言选择 中文(中国)
l 关键的一步:把 基类设置为 CTreeView
2 定义变量
在 TreeViewTippView.h 中定义两个 CString 变量,用于显示提示的内容。
注意:变量类型必须是 CString 的,并且最好是全局变量,若在函数中定义,需要在堆上分配( new )内存。代码需要稍微改动。
public :
CString m_tip1 ,m_tip2 ;
3 初始化变量
在构造函数中初始化,
CTreeViewTippView ::CTreeViewTippView ():m_tip1 (_T ("level-1" )),m_tip2 (_T ("level-2" ))
{
// TODO: 在此处添加构造代码
}
说明:m_tip1 用来显示一级目录的提示信息,m_tip1 用来显示二级目录的提示信息。
4 允许弹出提示窗口
在 OnInitialUpdate () 中添加函数 EnableToolTips (TRUE ); 允许弹出提示窗口
EnableToolTips (TRUE );
5 改变 CtreeCtrl 的风格
OnInitialUpdate () 改变 CtreeCtrl 的风格
long lStyle =GetWindowLong (this ->GetTreeCtrl ().m_hWnd ,GWL_STYLE );
lStyle |=TVS_HASBUTTONS |TVS_HASLINES |TVS_LINESATROOT |TVS_EDITLABELS ;
SetWindowLong (this ->GetTreeCtrl ().m_hWnd ,GWL_STYLE ,lStyle );
6 添加节点
给 CtreeView 添加几个节点,位置: OnInitialUpdate ()
HTREEITEM hroot =this ->GetTreeCtrl ().InsertItem (_T (" 根目录" ),0,0);
// 一级目录信息
HTREEITEM level1 =this ->GetTreeCtrl ().InsertItem (_T (" 一级目录" ),0,0,hroot );
this ->GetTreeCtrl ().SetItemData (level1 ,(DWORD_PTR )&m_tip1 );
// 二级目录信息
HTREEITEM level2 =this ->GetTreeCtrl ().InsertItem (_T (" 二级目录" ),0,0,level1 );
this ->GetTreeCtrl ().SetItemData (level2 ,(DWORD_PTR )&m_tip2 );
大家注意到了,根目录节点并没有添加提示信息,但是他能不能提示呢?是的,没有添加提示信息的节点也能显示提示功能 ,提示的内容是节点本身信息 ,当节点文本很长而又显示不完整的时候很有用处。
7 添加虚函数 OnToolHitTest
// 确定一个点是否位于指定工具的边界矩形之中并获
// 得工具的信息
INT_PTR CTreeViewTippView ::OnToolHitTest (CPoint point , TOOLINFO * pTI ) const
{
// TODO: Add your specialized code here and/or call the base class
RECT rect ;
UINT nFlags ;
HTREEITEM hitem = this ->GetTreeCtrl ().HitTest ( point , &nFlags );
// 判断若在某个项的文本上面
if ( hitem &&(nFlags & TVHT_ONITEMLABEL ) )
{
this ->GetTreeCtrl ().GetItemRect ( hitem , &rect , TRUE );
pTI ->hwnd = m_hWnd ;
pTI ->uId = (UINT_PTR )hitem ;
pTI ->lpszText = LPSTR_TEXTCALLBACK ;
pTI ->rect = rect ;
return pTI ->uId ;
}
return -1;
//return CTreeView::OnToolHitTest(point, pTI);
}
8 处理 TTN_NEEDTEXT 通知消息
在 VC2005 英文环境下,对 CtreeViewTippView 类的消息进行查找,居然没有找到 TTN_NEEDTEXT ,算了手动添加吧,记住:一共有三个地方需要改动:
第一:函数声明
在 TreeViewTippView.h 中添加代码
public :
BOOL OnToolTipText ( UINT id , NMHDR * pNMHDR , LRESULT * pResult );
第二:消息映射
在 TreeViewTippView.cpp 中找到
BEGIN_MESSAGE_MAP (CTreeViewTippView , CTreeView )
END_MESSAGE_MAP ()
修改为:
BEGIN_MESSAGE_MAP (CTreeViewTippView , CTreeView )
ON_NOTIFY_EX_RANGE (TTN_NEEDTEXTW , 0, 0xFFFF, OnToolTipText )
ON_NOTIFY_EX_RANGE (TTN_NEEDTEXTA , 0, 0xFFFF, OnToolTipText )
END_MESSAGE_MAP ()
第三:函数实现
在 TreeViewTippView.cpp 最后添加代码:
// 在运行时改变提示
//Tooltip 窗口在弹出之前,它给的父窗口发送通知消息 TTN_NEEDTEXT ,
// 请求得到要显示的文本。
BOOL CTreeViewTippView ::OnToolTipText ( UINT id , NMHDR * pNMHDR , LRESULT * pResult )
{
// need to handle both ANSI and UNICODE versions of the message
TOOLTIPTEXTA * pTTTA = (TOOLTIPTEXTA *)pNMHDR ;
TOOLTIPTEXTW * pTTTW = (TOOLTIPTEXTW *)pNMHDR ;
CString strTipText ;
UINT nID = (UINT )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 );
UINT nFlags ;
HTREEITEM hitem = this ->GetTreeCtrl ().HitTest ( pt , &nFlags ); //Get item pointed by mouse
strTipText .Format (_T ("%s" ) , this ->GetTreeCtrl ().GetItemText ( (HTREEITEM ) nID )); //get item text
DWORD dw = (DWORD )this ->GetTreeCtrl ().GetItemData ((HTREEITEM ) nID ); //get item data
CString * ItemData = (CString *)dw ; //CAST item data
if (ItemData !=NULL )
{
//CString s = ItemData; //pure virtual function
strTipText =CString (_T (" " )) + *ItemData ; //add node text to node data text
}
#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
}
说明:稍加修改也适合 CTreeCtrl 控件,当然也适合CListCtrl和CListBox控件
/********************************************************************************************************/
以上是我在网上搜到的给树形控件添加tip的方法,在visual studio 2005 里试验通过,但是在vc 6.0 中却无法通过,请问该怎么修改可以在vc 6.0 中正常工作
求解!!!!!!!!
[解决办法]
网上的很多帖子都是高版本的VS的,你用VC6.0的话,推荐你个好控件CPPtooltip,超级好用。codeproject和codeplex都有。
使用方法简便
//初始化标签控件
m_tooltip.Create(this);
m_tooltip.SetNotify();
m_tooltip.SetTransparency(0);
m_tooltip.SetBehaviour(PPTOOLTIP_NOCLOSE_OVER | PPTOOLTIP_CLOSE_LEAVEWND | PPTOOLTIP_DISABLE_AUTOPOP | PPTOOLTIP_MULTIPLE_SHOW);
m_tooltip.SetDelayTime(PPTOOLTIP_TIME_AUTOPOP,1000000);
m_tooltip.SetDelayTime(PPTOOLTIP_TIME_FADEIN,0);
m_tooltip.SetDelayTime(PPTOOLTIP_TIME_FADEOUT,50);
// 设置标签效果及渐变色
m_tooltip.SetColorBk(RGB(255, 255, 255),RGB(240, 247, 255),RGB(192, 192, 208));
m_tooltip.SetEffectBk(CPPDrawManager::EFFECT_SOFTBUMP,5);
//使用
m_tooltip.AddTool(控件,"标签内容");