在CTreeView中給CtreeCtrl增加提示(tip)的功能(圖解+源碼)
原創作者:boqing
http://tb.blog.csdn.net/TrackBack.aspx?PostId=1895519
http://download.csdn.net/source/290421
圖形界面如下:
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控件
別忘了給頂一下