Enhanced Title Tip Handling

Environment:This code was compiled with VC++ 6.0 and will work under both UNICODE and ANSI.

Previous submissions for Listview tooltips have used the complicated 'CellRectFromPoint' function written by Zafir Anjum. With the advent of IE3 and the common controls library version 4.70, we now have access to a simpler method via the function SubItemHitTest The following code uses only the 'OnToolTipText' function from the Zafir Anjum significantly simplifies the code and adds new feature. Tooltips are shown only for the cells in which text is partially visible.

int CMyLovelyListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
        LVHITTESTINFO   hi;
        int             nItem;
        CRect           rectCell;
        TCHAR           szText[81];
        LVITEM          lvi;

        // Do nothing in non-report mode
        if( !(GetStyle() & LVS_REPORT) )

	// Find item and subitem under a given point
        hi.pt = point;
        nItem = SubItemHitTest( &hi );
        if( nItem < 0 )
        // Retrieve text, image index and indent of the subitem
        lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_INDENT;
        lvi.iItem = nItem;
        lvi.iSubItem = hi.iSubItem;
        lvi.pszText = szText;
        lvi.cchTextMax = sizeof(szText)/sizeof(szText[0]);
        lvi.iIndent = 0;
        if( GetItem( &lvi ) == FALSE )
          return(-1);           // This should never happen, but...be paranoid

        // Retrieve bounding rect of the subitem.
        m_pListCtrl->GetSubItemRect( nItem, hi.iSubItem, LVIR_BOUNDS, rectCell );

        // Adjust indent if subitem has icon.
        if( lvi.iImage != -1 )

          lvi.iIndent += 20; // icon size(16) + some spacing

        // Strange, but GetStringWidth returns incorrect width of the string.
        // In all cases the width of the string is less than actual.
        // If somebody knows the reason please mail me.
        lvi.iIndent += 16;

        // Do not show tooltips if subitem is completely visible
        if( GetStringWidth( szText ) + lvi.iIndent < rectCell.Width() )

        // The following code was grabbed from Zafir Anjum's 'Tooltip for individual cells'
        pTI->rect = rectCell;
        pTI->hwnd = m_hWnd;
        pTI->uId = (UINT)(( nItem << 10 ) + (hi.iSubItem & 0x3ff) + 1 );
        pTI->lpszText = LPSTR_TEXTCALLBACK;
        return( pTI->uId );



  • And yet another way...

    Posted by Legacy on 11/08/2001 12:00am

    Originally posted by: Luis Garcia

    This is another way to get the width of a string from a list control:

    // Get text from list
    CString sItem = GetItemText( row, col );

    // Remember the margins, icon, etc
    CRect rcIcon;
    GetListCtrl().GetItemRect( row, &rcIcon, LVIR_ICON );
    int offset = ( col==0 ? 3*MARGIN + rcIcon.Width(): 2*MARGIN2 ) ;

    // Get proper size
    CDC dc;
    dc.SelectObject( GetFont() );
    CSize textwidth = dc.GetTextExtent(sItem).cx + offset;

    if ( textwidth <= colwidth )
    return -1;

  • Erroneous GetStringWidth

    Posted by Legacy on 11/17/2000 12:00am

    Originally posted by: Clemens Schmidt

    having encountered the same difficulty in GetStringWidth I made a test
    and found that the GetStringWidth calculates just the length of the string,
    forgetting the left and right margins. Taking Zafir Anjum's information that
    the margins are two blanks each, the modified getStringWidth function
    returns quite accurate results.


    int CmyListCtrl::getStringWidth(const CString& txt)
    if (txt.IsEmpty())
    return 0;

    CFont *pOldF, *pF = GetFont();
    CClientDC dc(this);
    pOldF = dc.SelectObject(pF);
    CRect r;
    dc.DrawText(txt, &r, DT_SINGLELINE|DT_CALCRECT);
    int wid = r.Width();
    dc.DrawText(_T(" "), &r, DT_SINGLELINE|DT_CALCRECT);
    wid += r.Width(); //add the width of four blanks
    wid += r.Width();
    return wid;

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Lenovo recommends Windows 8 Pro. "I dropped my laptop getting out of the taxi." This probably sounds familiar to most IT professionals. If your employees are traveling, you know their devices are in for a rough go. Whether it's a trip to the conference room or a convention out of town, any time equipment leaves a user's desk it is at risk of being put into harm's way. Stay connected at all times, whether at the office or on the go, with agile, durable, and flexible devices like the Lenovo® …

  • As the mobile enterprise marketplace expands and customer needs grow more diverse, Samsung recognizes that solution partners and developers play an essential role by continually innovating to meet their customers' needs. Samsung works to provide these developers and partners with the latest tools and resources needed to create these solutions. Read this program guide to learn how the Samsung Enterprise Alliance Program provides partners and developers with Samsung enterprise software development kits (SDKs) …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date