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) )
          return(-1);

	// Find item and subitem under a given point
        hi.pt = point;
        nItem = SubItemHitTest( &hi );
        if( nItem < 0 )
          return(-1);                   
        
        // 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() )
          return(-1);

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

History



Comments

  • 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.CreateCompatibleDC(NULL);
    dc.SelectObject( GetFont() );
    CSize textwidth = dc.GetTextExtent(sItem).cx + offset;

    if ( textwidth <= colwidth )
    return -1;

    Reply
  • Erroneous GetStringWidth

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

    Originally posted by: Clemens Schmidt

    Hi,
    
    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.

    Regards,
    clem.


    //////////////////////////////////////////////////////////////////////
    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();
    dc.SelectObject(pOldF);
    return wid;
    }

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

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • CentreCorp is a fully integrated and diversified property management and real estate service company, specializing in the "shopping center" segment, and is one of the premier retail service providers in North America. Company executives travel a great deal, carrying a number of traveling laptops with critical current business data, and no easy way to back up to the network outside the office. Read this case study to learn how CentreCorp implemented a suite of business continuity services that included …

Most Popular Programming Stories

More for Developers

RSS Feeds