ListCtrl设置ToolTip

岑畅
2023-12-01

这里是用一个类CToolTipListCtrl实现,它继承自CListCtrl。添加提示信息的时候只需要在OnToolTipText函数中if( nFlags & LVHT_ONITEMLABEL )代码块中设置你要显示的值给m_strToolTipText就可以了。这个时候你就可以为不同的单元格显示不同的提示信息,而且提示信息可以为任意多行,提示信息可以使用“\n”分行。

 
ToolTipListCtrl.h的代码如下:

#pragma once


// CToolTipListCtrl

class CToolTipListCtrl : public CListCtrl
{
 DECLARE_DYNAMIC(CToolTipListCtrl)

public:
 CToolTipListCtrl();
 virtual ~CToolTipListCtrl();

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

protected:
 virtual afx_msg BOOL OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT *  pResult );
 DECLARE_MESSAGE_MAP()
private:
 CString m_strToolTipText;//Item的提示信息
};

 

ToolTipListCtrl.cpp的代码如下:


#include "stdafx.h"
#include "ListCtrlToolTipTest.h"
#include "ToolTipListCtrl.h"


// CToolTipListCtrl

IMPLEMENT_DYNAMIC(CToolTipListCtrl, CListCtrl)
CToolTipListCtrl::CToolTipListCtrl()
{
}

CToolTipListCtrl::~CToolTipListCtrl()
{
}


BEGIN_MESSAGE_MAP(CToolTipListCtrl, CListCtrl)
 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
END_MESSAGE_MAP()

 

// CToolTipListCtrl 消息处理程序

int CToolTipListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const {

 //See if the point falls onto a list item
 //UINT nFlags = 0;

 LVHITTESTINFO lvhitTestInfo;

 lvhitTestInfo.pt = point;

 int nItem = ListView_SubItemHitTest(
  this->m_hWnd,
  &lvhitTestInfo);
 int nSubItem = lvhitTestInfo.iSubItem;

 UINT nFlags =   lvhitTestInfo.flags;

 //nFlags is 0 if the SubItemHitTest fails
 //Therefore, 0 & <anything> will equal false
 if (nFlags & LVHT_ONITEMLABEL){
  //If it did fall on a list item,
  //and it was also hit one of the
  //item specific sub-areas we wish to show tool tips for

  //Get the client (area occupied by this control
  RECT rcClient;
  GetClientRect( &rcClient );

  //Fill in the TOOLINFO structure
  pTI->hwnd = m_hWnd;
  pTI->uId = (UINT) (nItem * 100 + nSubItem);
  pTI->lpszText = LPSTR_TEXTCALLBACK;
  pTI->rect = rcClient;

  return pTI->uId; //By returning a unique value per listItem,
  //we ensure that when the mouse moves over another list item,
  //the tooltip will change
 }else{
  //Otherwise, we aren't interested, so let the message propagate
  return -1;
 }
}

 

BOOL CToolTipListCtrl::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ){

 //VC6.0则用下面这句
 //_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();

 //VC2003则用这句
 AFX_MODULE_THREAD_STATE* pThreadState = AfxGetModuleThreadState();
 CToolTipCtrl *pToolTip = pThreadState->m_pToolTip;
 pToolTip->SetMaxTipWidth(500);

 

 //Handle both ANSI and UNICODE versions of the message
 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
 TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;


 if( (pNMHDR->idFrom == (UINT)m_hWnd) &&
  ( ((pNMHDR->code == TTN_NEEDTEXTA) && (pTTTA->uFlags & TTF_IDISHWND)) ||
  ((pNMHDR->code == TTN_NEEDTEXTW) && (pTTTW->uFlags & TTF_IDISHWND)) ) ){
   return FALSE;
  }

  *pResult = 0;

  //Get the mouse position
  const MSG* pMessage;
  pMessage = GetCurrentMessage();
  ASSERT ( pMessage );
  CPoint pt;
  pt = pMessage->pt; //Get the point from the message
  ScreenToClient( &pt );

 

  LVHITTESTINFO lvhitTestInfo;

  lvhitTestInfo.pt = pt;

  int nItem = SubItemHitTest(&lvhitTestInfo);
  int nSubItem = lvhitTestInfo.iSubItem;

  UINT nFlags =   lvhitTestInfo.flags;


  if( nFlags & LVHT_ONITEMLABEL ){

   //在这里设置提示信息显示的内容
   m_strToolTipText = GetItemText(nItem,nSubItem) + _T("\nTEST");
   pTTTA->lpszText = (LPSTR)(LPWSTR)(LPCWSTR)m_strToolTipText;
   pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_strToolTipText;

 

   //{{下面为提供提示信息的另外一种方法
   //   CString strTipText;//提示信息内容
   //#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

   //}}另外一种提示方法结束


   return FALSE; 

  }

  return FALSE;
}

 

 类似资料: