VC中给树形控件的图标加上工具提示

原创 2003年09月17日 10:54:00
VC中给树形控件的图标加上工具提示



我从没有在任何一个应用程序中看到过图标的工具提示。有时候查遍了整个帮助
文档也没有明白某个图标是什么意思。如果能在自己的程序中为图标加上工具提
示,一定会使界面的友好性大大增加。本文中以树形控件为例,详细介绍了在VC
中使用MFC提供的机制来实现图标工具提示的方法。

---- 第一步:使控件可以显示工具提示

---- 调用EnableToolTips(TRUE)使一个窗口可以显示工具提示。在什么地方插入
这条代码最好呢?在类的PreSubclassWindow()中。因为不管一个控件如何被创建
,MFC都会调用此函数。而其他的函数则不一定会被调用。以OnCreate()为例,如
果调用Create()或CreateEx()创建一个控件,OnCreate()会被调用,而如果一个
控件是从对话框资源创建,OnCreate()就不会被调用。

实现代码如下:
void CTreeCtrlX::PreSubclassWindow()
{
CTreeCtrl::PreSubclassWindow();

EnableToolTips(TRUE);
}

---- 第二步:重载虚函数OnToolHitTest()
---- MFC调用函数来确定在某个点是否应该显示工具提示。MSDN建议如果鼠标落
在应该显示工具提示的点上,返回值1。这并不完全正确。这个函数应该返回不同
的值来区分窗口中不同的应该显示提示的区域。

---- 在这个函数中,本文只处理鼠标落在节点图标或节点状态图标上的情况。读
者可以按照自己的情况向树的其他元素上添加工具提示。在两种情况下,都要计
算图标的区域,并且把TOOLINFO的uID设为鼠标所在点的树节点的句柄。注意,尽
管对于节点图标和节点状态图标,使用了相同的id,但返回值并不相同。不同的
返回值迫使MFC更新工具提示。

---- 虽然我们可以在此函数中给出工具提示,但因为鼠标的每次移动都会调用此
函数,太多的处理并不是一个好注意,所以我们在其他的函数中处理应该显示什
么提示的问题。

类声明中的代码如下所示:
// Overrides
// ClassWizard generated
virtual function overrides
//{{AFX_VIRTUAL(CTreeCtrlX)
protected:

virtual int OnToolHitTest
( CPoint point, TOOLINFO* pTI ) const;
//}}AFX_VIRTUAL

实现代码如下所示:
int CTreeCtrlX::OnToolHitTest
(CPoint point, TOOLINFO * pTI) const
{
RECT rect;

UINT nFlags;
HTREEITEM hitem = HitTest( point, &nFlags );
if( nFlags & TVHT_ONITEMICON )
{
CImageList *pImg = GetImageList( TVSIL_NORMAL );
IMAGEINFO imageinfo;
pImg- >GetImageInfo( 0, &imageinfo );

GetItemRect( hitem, &rect, TRUE );
rect.right = rect.left - 2;
rect.left -= (imageinfo.rcImage.right + 2);

pTI- >hwnd = m_hWnd;
pTI- >uId = (UINT)hitem;
pTI- >lpszText = LPSTR_TEXTCALLBACK;
pTI- >rect = rect;
return pTI- >uId;
}
else if( nFlags & TVHT_ONITEMSTATEICON )
{
CImageList *pImg = GetImageList( TVSIL_NORMAL );
IMAGEINFO imageinfo;
pImg- >GetImageInfo( 0, &imageinfo );

GetItemRect( hitem, &rect, TRUE );
rect.right = rect.left -
(imageinfo.rcImage.right + 2);

pImg = GetImageList( TVSIL_STATE );
rect.left = rect.right - imageinfo.rcImage.right ;

pTI- >hwnd = m_hWnd;
pTI- >uId = (UINT)hitem;
pTI- >lpszText = LPSTR_TEXTCALLBACK;
pTI- >rect = rect;

// 返回与节点图标不同的值
return pTI- >uId*2;
}
return -1;
}

---- 第三步:处理TTN_NEEDTEXT消息;
---- 加入一个函数处理TTN_NEEDTEXT消息通知。当工具处理控制需要知道应该显
示什么信息时,这条消息被发出。由于上一步中我们给TOOLINFO的lpszText赋值
为LPSTR_TEXTCALLBACK,所以我们要处理这个消息VC的ClassWizard并不支持这条
消息被映射,所以只有我们自己加入这条消息的映射机制加入到MESSAGE_MAP中去
。我们不得不处理这个消息的两个版本,TTN_NEEDTEXTA和TTN_NEEDTEXTA。消息
映射的代码如下所示:

BEGIN_MESSAGE_MAP(CTreeCtrlX, CTreeCtrl)
//{{AFX_MSG_MAP(CTreeCtrlX)

//}}AFX_MSG_MAP
ON_NOTIFY_EX_RANGE
(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
ON_NOTIFY_EX_RANGE
(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
END_MESSAGE_MAP()

下面的代码是加到类声明中:
protected:
//{{AFX_MSG(CTreeCtrlX)

//}}AFX_MSG
afx_msg BOOL OnToolTipText
( UINT id, NMHDR * pNMHDR, LRESULT * pResult );
DECLARE_MESSAGE_MAP()

---- 现在讨论这个函数本身的实现。为了适应不同的语言字符集,ANSI字符集和
UNICODE字符集都必须被处理,处理过程会有些不同。此处对树形控件的本身产生
的ToolTip消息不予处理,过滤掉上述消息的原则是树形控件本身产生的消息的ID
是树形控件窗口的句柄,并且有TTF_IDISHWND标志。根据鼠标位置可以确定应该
给出节点图标还是状态图标的工具提示。本文根据笔者画的图显示了一些无关紧
要的提示,读者做这一步时应该加入一些有意义的提示。当然,本文假定控件包
含节点图标和状态图标。如不包含,计算鼠标位置时要注意 不要计算错误。

BOOL CTreeCtrlX::OnToolTipText
( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
{
// 需要处理ANSI和UNICODE两种格式
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
CString strTipText;
UINT nID = pNMHDR- >idFrom;

// 不必处理树自己发出的ToolTip消息
if( nID == (UINT)m_hWnd &&
(( pNMHDR- >code == TTN_NEEDTEXTA &&
pTTTA- >uFlags & TTF_IDISHWND ) ||
( pNMHDR- >code == TTN_NEEDTEXTW &&
pTTTW- >uFlags & TTF_IDISHWND ) ) )
return FALSE;

// 得到鼠标位置
const MSG* pMessage;
CPoint pt;
pMessage = GetCurrentMessage();
ASSERT ( pMessage );
pt = pMessage- >pt;
ScreenToClient( &pt );

UINT nFlags;
HTREEITEM hitem = HitTest( pt, &nFlags );
if( nFlags & TVHT_ONITEMICON )
{
int nImage, nSelImage;
GetItemImage( (HTREEITEM ) nID, nImage, nSelImage );
switch(nImage)
{
case 0:
strTipText = "叉";
break;
case 1:
strTipText = "加号";
break;
case 2:
strTipText = "菱形";
break;
}
}
else
{
if( (GetItemState( (HTREEITEM ) nID,
TVIS_STATEIMAGEMASK ) > >12 ) == 2 )
strTipText.Format( "此节点被选中" );
else
strTipText.Format( "此节点未被选中" );
}

#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; // 消息处理完毕
}

---- 本文程序在Win9x,VC6.0下调试通过。



VC中树控件的用法

树形控件可以用于树形的结构,其中有一个根接点(Root)然后下面有许多子结点,而每个子结点上有允许有一个或多个或没有子结点。MFC中使用CTreeCtrl类来封装树形控件的各种操作。通过调用BOOL ...
  • liqing19850102
  • liqing19850102
  • 2012年05月29日 22:19
  • 7538

MFC树控件节点后加图标实现

MFC树控件未提供节点后加图标的方法,需要自己重绘来实现。 主要方法是,响应NM_CUSTOMDRAW消息,在每个节点后添加自己要展示的图标。 关于NM_CUSTOMDRAW消息的说明,见http...
  • segen_jaa
  • segen_jaa
  • 2012年08月16日 15:50
  • 6515

MFC 为树形控件添加图标

添加控件,树形控件,静态文本框和编辑框。树形控件属性Has Buttons,Has Lines, Lines At Root 勾选为True. 并为树形控件添加变量,m_webTree ...
  • fulianzhou
  • fulianzhou
  • 2015年10月07日 12:25
  • 2441

VC树形控件控件(基础)

树形控件是一种可以分级显示项目列表的窗口,其所含项目以相互关联的方式显示在控件中,通过点击位于某个层次的项目 节点可以展开下一层次中从属于该节点的所有项目。树形控件非常适合于管理那些层次较多且相互间隶...
  • tengxiaoming
  • tengxiaoming
  • 2010年06月03日 01:03
  • 3819

如何编辑VC中的树形控件的结点文本!

对于树形控件有两个消息:TVI_BEGINEDITLABLE与TVI_ENDEDITLABLE对应的函数为:void OnBeginlabeleditFriendlistTree(NMHDR* pNM...
  • sdl111
  • sdl111
  • 2005年09月30日 16:26
  • 1757

CTreeCtrl添加图标几种方法

ASSERT(pmyTreeCtrl-> GetImageList(TVSIL_NORMAL)   ==   NULL);  pmyTreeCtrl-> SetImageList(p...
  • sqysqy123456
  • sqysqy123456
  • 2014年02月28日 13:00
  • 751

为树形控件的每个节点前添加不同的图标

HICON icon[4]; icon[0] = AfxGetApp()->LoadIcon(IDI_ICONA); icon[1] = AfxGetApp()->LoadIcon(IDI_ICO...
  • ilikehigame
  • ilikehigame
  • 2015年02月05日 15:10
  • 1248

vc++树状控件(TreeCtrl)用法

/////////////////////////添加树状///////////////////////////// HTREEITEM hItem,hChildItem; //定义树状控件的句...
  • lxh1230119
  • lxh1230119
  • 2012年07月04日 20:28
  • 7819

MFC学习之 树控件加图标

树控件学习:http://blog.csdn.net/shuilan0066/article/details/6638504 方法很多,常用到的有这两个:截图: 方法一:(加 ico图标,...
  • abidepan
  • abidepan
  • 2012年08月30日 00:30
  • 6444

VC 添加与显示工具栏提示信息

对于包含在 CFrameWnd 派生的父窗口中的按钮或其他控件,工具提示会自动显示。这是因为 CFrameWnd 有一个用于 TTN_GETDISPINFO 通知的默认处理程序,该程序处理来自与控件关...
  • scollins
  • scollins
  • 2010年08月27日 13:46
  • 2082
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VC中给树形控件的图标加上工具提示
举报原因:
原因补充:

(最多只允许输入30个字)