在CTreeView中給CtreeCtrl增加提示(tip)的功能(圖解+源碼)

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控件

別忘了給頂一下

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章