Windows/MFC
CListCtrl & Tooltip TitleTip
aucd29
2013. 10. 2. 18:04
URL : http://www.codeguru.com/cpp/controls/listview/tooltiptitletip/article.php/c4161/
int CDataTipListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
{
CRect rect;
GetClientRect(&rect);
if(rect.PtInRect(point))
{
if(GetItemCount())
{
int nTopIndex = GetTopIndex();
int nBottomIndex = nTopIndex + GetCountPerPage();
if(nBottomIndex > GetItemCount())
nBottomIndex = GetItemCount();
for(int nIndex = nTopIndex;
nIndex < = nBottomIndex; nIndex++)
{
GetItemRect(nIndex, rect, LVIR_BOUNDS);
if(rect.PtInRect(point))
{
pTI->hwnd = m_hWnd;
pTI->uId = (UINT)(nIndex+1);
pTI->lpszText = LPSTR_TEXTCALLBACK;
pTI->rect = rect;
return pTI->uId;
}
}
}
}
return -1;
}
BOOL CDataTipListCtrl::OnToolTipText(UINT id,
NMHDR* pNMHDR,
LRESULT* pResult)
{
// I want to implement this in PreSubclassWindow(),
// but it crashes.
if(!m_bToolTipCtrlCustomizeDone)
{
AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
CToolTipCtrl *pToolTip = pThreadState->m_pToolTip;
// Set max tip width in pixel.
// you can change delay time, tip text or background
// color also. enjoy yourself!
pToolTip->SetMaxTipWidth(500);
m_bToolTipCtrlCustomizeDone = TRUE;
}
// need to handle both ANSI and UNICODE versions of
// the message
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
UINT nID = pNMHDR->idFrom;
if(nID == 0) // Notification in NT from automatically
return FALSE; // created tooltip
int nItem = nID - 1;
CString strTip;
TCHAR buf[MAX_TIP_LENGTH+1];
HDITEM hdCol;
hdCol.mask = HDI_TEXT;
hdCol.pszText = buf;
hdCol.cchTextMax = MAX_TIP_LENGTH;
int nNumCol = m_Header.GetItemCount();
for(int col=0; col < nNumCol; col++)
{
m_Header.GetItem(col, &hdCol);
strTip += hdCol.pszText;
strTip += _T(": ");
strTip += GetItemText(nItem, col);
if(col < nNumCol-1) strTip += _T('\n');
}
#ifndef _UNICODE
if(pNMHDR->code == TTN_NEEDTEXTA)
{
if(m_pchTip != NULL)
delete m_pchTip;
m_pchTip = new TCHAR[strTip.GetLength()+1];
lstrcpyn(m_pchTip, strTip, strTip.GetLength());
m_pchTip[strTip.GetLength()] = 0;
pTTTW->lpszText = (WCHAR*)m_pchTip;
}
else
{
if(m_pwchTip != NULL)
delete m_pwchTip;
m_pwchTip = new WCHAR[strTip.GetLength()+1];
_mbstowcsz(m_pwchTip, strTip, strTip.GetLength());
m_pwchTip[strTip.GetLength()] = 0; // end of text
pTTTW->lpszText = (WCHAR*)m_pwchTip;
}
#else
if(pNMHDR->code == TTN_NEEDTEXTA)
{
if(m_pchTip != NULL)
delete m_pchTip;
m_pchTip = new TCHAR[strTip.GetLength()+1];
_wcstombsz(m_pchTip, strTip, strTip.GetLength());
m_pchTip[strTip.GetLength()] = 0; // end of text
pTTTA->lpszText = (LPTSTR)m_pchTip;
}
else
{
if(m_pwchTip != NULL)
delete m_pwchTip;
m_pwchTip = new WCHAR[strTip.GetLength()+1];
lstrcpyn(m_pwchTip, strTip, strTip.GetLength());
m_pwchTip[strTip.GetLength()] = 0;
pTTTA->lpszText = (LPTSTR) m_pwchTip;
}
#endif
*pResult = 0;
return TRUE; // message was handled
}
CDataTipListCtrl::~CDataTipListCtrl()
{
if(m_pchTip != NULL)
delete m_pchTip;
if(m_pwchTip != NULL)
delete m_pwchTip;
}
int CDataTipListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
{
CRect rect;
GetClientRect(&rect);
if(rect.PtInRect(point))
{
if(GetItemCount())
{
int nTopIndex = GetTopIndex();
int nBottomIndex = nTopIndex + GetCountPerPage();
if(nBottomIndex > GetItemCount())
nBottomIndex = GetItemCount();
for(int nIndex = nTopIndex;
nIndex < = nBottomIndex; nIndex++)
{
GetItemRect(nIndex, rect, LVIR_BOUNDS);
if(rect.PtInRect(point))
{
pTI->hwnd = m_hWnd;
pTI->uId = (UINT)(nIndex+1);
pTI->lpszText = LPSTR_TEXTCALLBACK;
pTI->rect = rect;
return pTI->uId;
}
}
}
}
return -1;
}
BOOL CDataTipListCtrl::OnToolTipText(UINT id,
NMHDR* pNMHDR,
LRESULT* pResult)
{
// I want to implement this in PreSubclassWindow(),
// but it crashes.
if(!m_bToolTipCtrlCustomizeDone)
{
AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
CToolTipCtrl *pToolTip = pThreadState->m_pToolTip;
// Set max tip width in pixel.
// you can change delay time, tip text or background
// color also. enjoy yourself!
pToolTip->SetMaxTipWidth(500);
m_bToolTipCtrlCustomizeDone = TRUE;
}
// need to handle both ANSI and UNICODE versions of
// the message
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
UINT nID = pNMHDR->idFrom;
if(nID == 0) // Notification in NT from automatically
return FALSE; // created tooltip
int nItem = nID - 1;
CString strTip;
TCHAR buf[MAX_TIP_LENGTH+1];
HDITEM hdCol;
hdCol.mask = HDI_TEXT;
hdCol.pszText = buf;
hdCol.cchTextMax = MAX_TIP_LENGTH;
int nNumCol = m_Header.GetItemCount();
for(int col=0; col < nNumCol; col++)
{
m_Header.GetItem(col, &hdCol);
strTip += hdCol.pszText;
strTip += _T(": ");
strTip += GetItemText(nItem, col);
if(col < nNumCol-1) strTip += _T('\n');
}
#ifndef _UNICODE
if(pNMHDR->code == TTN_NEEDTEXTA)
{
if(m_pchTip != NULL)
delete m_pchTip;
m_pchTip = new TCHAR[strTip.GetLength()+1];
lstrcpyn(m_pchTip, strTip, strTip.GetLength());
m_pchTip[strTip.GetLength()] = 0;
pTTTW->lpszText = (WCHAR*)m_pchTip;
}
else
{
if(m_pwchTip != NULL)
delete m_pwchTip;
m_pwchTip = new WCHAR[strTip.GetLength()+1];
_mbstowcsz(m_pwchTip, strTip, strTip.GetLength());
m_pwchTip[strTip.GetLength()] = 0; // end of text
pTTTW->lpszText = (WCHAR*)m_pwchTip;
}
#else
if(pNMHDR->code == TTN_NEEDTEXTA)
{
if(m_pchTip != NULL)
delete m_pchTip;
m_pchTip = new TCHAR[strTip.GetLength()+1];
_wcstombsz(m_pchTip, strTip, strTip.GetLength());
m_pchTip[strTip.GetLength()] = 0; // end of text
pTTTA->lpszText = (LPTSTR)m_pchTip;
}
else
{
if(m_pwchTip != NULL)
delete m_pwchTip;
m_pwchTip = new WCHAR[strTip.GetLength()+1];
lstrcpyn(m_pwchTip, strTip, strTip.GetLength());
m_pwchTip[strTip.GetLength()] = 0;
pTTTA->lpszText = (LPTSTR) m_pwchTip;
}
#endif
*pResult = 0;
return TRUE; // message was handled
}
CDataTipListCtrl::~CDataTipListCtrl()
{
if(m_pchTip != NULL)
delete m_pchTip;
if(m_pwchTip != NULL)
delete m_pwchTip;
}