Click here to Skip to main content
15,946,342 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
When a list control (CListCtrl) has the extended style LVS_EX_INFOTIP, resting the mouse pointer over an item that ends in ellipses (...) does not always result in a tool tip that shows the
full text. Is there anything that can be done about this?

The following web page discusses this problem but does not answer it completely.

What I have tried:

As a workaround, I resize columns to match the content:
m_lc.SetColumnWidth (n, LVSCW_AUTOSIZE_USEHEADER);
However, this does not fix the problem.
Updated 28-Dec-16 23:55pm

1 solution

A solution might be handling OnToolHitTest and displaying the tooltip yourself.

Code snippet from an existing project (edited and shortened):
INT_PTR CMyListCtrl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
    // Check if clicked inside list area (including header). 
    // Must use client rect to exclude scroll bars.
    CRect rectList;
    if (!rectList.PtInRect(point))
        return CListCtrl::OnToolHitTest(point, pTI);

    LVHITTESTINFO tHitTest; = point;
    // CListCtrl::SubItemHitTest() is not declared as const.
    // However, it is an inline function doing this (see afxcmn2.inl):
    ::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, 0, reinterpret_cast<LPARAM>(&tHitTest));
    // on empty row or dummy column
    if (tHitTest.iItem < 0)
        return -1;

    // Again, CListCtrl::GetSubItemRect() is not declared as const.
    // So send message here (see winctrl2.cpp).
    RECT rect; = tHitTest.iSubItem;
    rect.left = LVIR_BOUNDS;
    if (!::SendMessage(m_hWnd, LVM_GETSUBITEMRECT, tHitTest.iItem, reinterpret_cast<LPARAM>(&rect)))
        return -1;

    CString strTipText;
    // Check if on header.
    // This requires knowing the height of the header.
    // GetHeaderHeight() must be implemented yourself!
    int nHeaderHeight = GetHeaderHeight();
    if (tHitTest.iItem == 0 && point.y < nHeaderHeight)
        HDITEM hdi; 
        // EDIT: Replaced char by TCHAR
        TCHAR buf[255];
        hdi.mask = HDI_TEXT;
        hdi.cchTextMax = sizeof(buf) / sizeof(TCHAR);
        hdi.pszText = buf;
        GetHeaderCtrl()->GetItem(tHitTest.iSubItem, &hdi); 
        strTipText = hdi.pszText;
        strTipText = GetItemText(tHitTest.iItem, tHitTest.iSubItem);
    int nSize = strTipText.GetLength();
    if (0 == nSize)
        return -1;
    // Make an ID from row and column number used also as return value.
    // We must add 1 to ensure that ID is not zero.
    // Even when passing the tooltip text here, we must return a unique ID.
    // Tooltips are not displayed when returning the same ID value as for the last call.
    pTI->uId = (UINT)((tHitTest.iItem << 8) + (tHitTest.iSubItem & 0xff) + 1);
    pTI->rect = rect;
    pTI->hwnd = m_hWnd;
    // Passing tool tip text using an allocated buffer.
    // By specifying the tooltip text here, we can omit the OnToolTipNotify handler.
    // If text is passed by pointer and pTI->hinst is NULL, the memory must be allocated from the local heap.
    // FilterToolTipMessage() will free the memory (see tooltip.cpp from MFC).
    // Using this allows tooltip text with more than 80 characters.
    pTI->lpszText = new TCHAR [++nSize];
    _tcscpy(pTI->lpszText, strTipText.GetString());
    pTI->hinst = NULL;
    return pTI->uId;
Share this answer

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900