为TreeCtrl中的项增加ToolTip

要点:通过OnToolHitTest来增加ToolTip,CTreeCtrl::HitTest(...)的使用,TTN_NEEDTEXT消息的处理。

定义一个新类,有CTreeCtrl派生
Step 1:打开ToolTip 功能
void CTreeCtrlX::PreSubclassWindow()
{
     CTreeCtrl::PreSubclassWindow();

     EnableToolTips(TRUE);
}


Step 2: OnToolHitTest() 的重载
首先通过HitTest决定是否增加ToolTip,如果需要则返回非零。

在本例中ToolTip使用了LPSTR_TEXTCALLBACK,而没有立即设定显示字符串。

在本例只在鼠标指向每项的图片时才显示ToolTip



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 value should be different from that used for item icon
         return pTI->uId*2;
     }
     return -1;
}
Step 3: ?? TTN_NEEDTEXT
由于在增加ToolTip是使用用了 LPSTR_TEXTCALLBACK,因此ToolTip在显示时会发送该消息来得到显示字符串。

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()

BOOL CTreeCtrlX::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 = 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();
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 );
strTipText.Format( "Image : %d", nImage );
}
else
{
strTipText.Format( "State : %d", GetItemState( (HTREEITEM ) nID,
      TVIS_STATEIMAGEMASK ) );
}

#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
}

=---------------------------------------------------

m_tooltip.Create(this);
m_tooltip.Activate(TRUE);
m_tooltip.SetTipBkColor(RGB(240,220,2040));
m_tooltip.SetTipTextColor(RGB(80,0,200));
m_tooltip.SetDelayTime(500);
m_tooltip.SetMaxTipWidth(5000);//只要加上此句,下面的就可以换行了!!用/r/n换行
m_tooltip.AddTool(GetDlgItem(IDC_EDIT1), "这里输入大概的编号,/r/n系统将会为你找到最近的最匹配的一条记录! ");

猜你喜欢

转载自blog.csdn.net/wingsing2010/article/details/5779477
今日推荐