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