List Control with Tooltips

This article contains a simple CListCtrl wrapper called CFileDropListCtrl which was made to wrap a CListCtrl so it can display ToolTip text for each item in the control regardless of the style of the view : REPORT, LIST, ICON

Previous articles only listed tooltip text for the Report view.

It was adapted from a previous wrapper which adds Drag&Drop to the control so it can receive files.

The tooltip code was also adapted from a previous tooltip article in this section which supplied tooltip for only REPORT style views. The author simply left out the ability to handle Icon view reports which don't use a column width, but instead just use a rect boundary. To display ICON tooltips, simply includ an IF statment to detect which form the control is in, and if it's an icon view, then set the columnwidth to an arbitrary 10000 so it will not be used in detection. In any case, here is the code below.

Usage

  1. Include the 2 files in your project.
  2. Use Classwizard to add a member variable for your CListCtrl such as m_List.
  3. Change in the .h file, CListCtrl m_List change it to CFileDropListCtrl m_List. Thats it!
  4. Modify the ToolTip function to display any other text you like, currently it just displays the item's name.

Note the detection of the control type. Report style views have a column width for each item which we use in mouse-click detection for the tooltip. In List and Icon views, we do not have a column width. So, in those cases we set ColumnWidth to an arbitrary high value so it will not be used, and also column count to 1.

// If not REPORT style for the list, then use 1 column
// Otherwise, find the column in the report style view.
if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
{
 // Window is not Report style, so no headers. Deal with it!
 nColumnCount = 1;
}
else
{
 // Get the number of columns in Report style.
 pHeader = (CHeaderCtrl*)GetDlgItem(0);
 nColumnCount = pHeader->GetItemCount();
}

Here we see the rectangle boundary for Icon, List, and Report views.

// Get bounding rect of item and check whether point falls in it.
CRect rect, rectLabel;
if( (GetWindowLong(m_hWnd, GWL_STYLE) 
& LVS_TYPEMASK) != LVS_REPORT )
{
 // If not Report style, get label / icon boundaries.
 GetItemRect( row, &rect, LVIR_ICON );
 GetItemRect( row, &rectLabel, LVIR_LABEL );
}
else
{
 // If Report style, get bounds of cell.
 GetItemRect( row, &rect, LVIR_BOUNDS );
}

if( rect.PtInRect(point) ||
rectLabel.PtInRect(point))
{

Finally, to change what is displayed in the ToolTip simple change the line GetItemText() below to display whatever you like.

BOOL CFileDropListCtrl::OnToolTipText( UINT id, 
                                       NMHDR * pNMHDR, 
                                       LRESULT * pResult )
{
 // need to handle both ANSI and UNICODE versions of the message
 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
 TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
 CString strTipText;
 UINT nID = pNMHDR->idFrom;

if( nID == 0 ) // Notification in NT from automatically
 return FALSE; // created tooltip

int row = ((nID-1) >> 10) & 0x3fffff ;
int col = (nID-1) & 0x3ff;

// Use Item's name as the tool tip. Change this for something different.
// Like use its file size, etc.
strTipText = GetItemText( row, col );

That is it. Here are the 2 files to include in your project.

Downloads

Download source - 17 Kb