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