Detecting column index of the item clicked

The HitTest() function provided by the CListCtrl class returns only the row index of the item that falls under the point being tested. The HitTest() also has the drawback that it fails if the point is not directly over the first column. To determine the row of the item, we use GetItemRect() to get the rectangular bounds of each visible row and use PtInRect() to determine if the point falls within this rectangle. Once we know the row, we use GetColumnWidth() to determine the bounding rect for each cell and then test the point against each of these bounding rectangles.
// HitTestEx	- Determine the row index and column index for a point
// Returns	- the row index or -1 if point is not over a row
// point	- point to be tested.
// col		- to hold the column index
int CMyListCtrl::HitTestEx(CPoint &point, int *col) const
{
	int colnum = 0;
	int row = HitTest( point, NULL );
	
	if( col ) *col = 0;

	// Make sure that the ListView is in LVS_REPORT
	if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
		return row;

	// Get the top and bottom row visible
	row = GetTopIndex();
	int bottom = row + GetCountPerPage();
	if( bottom > GetItemCount() )
		bottom = GetItemCount();
	
	// Get the number of columns
	CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
	int nColumnCount = pHeader->GetItemCount();

	// Loop through the visible rows
	for( ;row <= bottom;row++)
	{
		// Get bounding rect of item and check whether point falls in it.
		CRect rect;
		GetItemRect( row, &rect, LVIR_BOUNDS );
		if( rect.PtInRect(point) )
		{
			// Now find the column
			for( colnum = 0; colnum < nColumnCount; colnum++ )
			{
				int colwidth = GetColumnWidth(colnum);
				if( point.x >= rect.left 
					&& point.x <= (rect.left + colwidth ) )
				{
					if( col ) *col = colnum;
					return row;
				}
				rect.left += colwidth;
			}
		}
	}
	return -1;
}
 

Date Last Updated: April 3, 1999



Comments

  • Missing licencing information

    Posted by freds72 on 11/16/2010 11:48am

    Would it be possible to precise licencing terms for the related code source? Regards Frederic

    Reply
  • Misses the last row

    Posted by Mike Pliam on 04/28/2007 03:17am

    Has no one noticed that this technique misses the last visible row? How to fix that ?

    Reply
  • help me!

    Posted by Legacy on 08/05/2002 12:00am

    Originally posted by: hhh

    where can i get the point parameter piont in function HitTestEx(CPoint &point, int *col) const from?
    when the mouse point on the ListCtrl,how can i get the point? help me ?tanks a lot!

    Reply
  • Also can use SubItemHitTest

    Posted by Legacy on 05/31/2000 12:00am

    Originally posted by: wen111

    also can use SubItemHitTest of the CListCtrl for functions like "OnLButtonDown" which don't have a struct passed (see Matt Parker's post below). You can check the definition of
    
    LVHITTESTINFO struct in MSDN library.

    OnLButtonDown(UINT nFlags, CPoint point)
    {
    LVHITTESTINFO lvhti;
    lvhti.pt = point;
    GetListCtrl().SubItemHitTest(&lvhti);

    if(lvhti.flags & LVHT_ONITEM)
    {
    CString str;
    str.Format("iItem = %d, iSubItem = %d", lvhti.iItem, lvhti.iSubItem);
    AfxMessageBox(str);
    }
    }

    • Does not work

      Posted by SteveS on 08/20/2004 03:31pm

      This does not work for items in a listview unless the user happens to be over the first column of the list.

      Reply
    Reply
  • If I don't use mouse

    Posted by Legacy on 08/03/1999 12:00am

    Originally posted by: Wen

    If I use tab key and space bar to push the column
    how can I detect the item number

    • how about selecting using ARROW KEYS?

      Posted by Maverick5877 on 07/13/2005 05:53am

      Maybe you have an idea about getting the selected column index using arrow keys... 
      i have problems on many ListCtrl events.. i.e.
      
         void ...OnLvnItemchangedListService(NMHDR *pNMHDR, LRESULT *pResult)
      {
      	
          LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
         //   pNMLV->subitem is always zero even if I have selected on    
         //columns other than the first one..
      }
      
      with   OnNMClick().. subitem just works fine but 
      with all other event messages specially with the LVN_????() messages, 
      the subitem  value of pNMHDR is not properly updated..

      Reply
    • And if there is no click?

      Posted by SteveS on 08/20/2004 03:33pm

      What if you're just hovering over the control and you don't click?

      Reply
    Reply
  • Fix so that hit test works with reordered columns

    Posted by Legacy on 07/05/1999 12:00am

    Originally posted by: Andrew Skowronski

    The latests version of the List Control allows user
    
    to reorder columns with drag and drop when
    the LVS_EX_HEADERDRAGDROP flag is set.

    This HitTestEx function doesn't work properly for
    such a reordered list control. Forunately the
    fix pretty straightforward.

    I've renamed the colnum variable to colpos to try
    and be a little more clear.
    I've changed the "for" loop to look at the columns
    in the order they are currently sorted, not in
    the order of their index.

    Note:
    I happen to know the maximum number of columns.
    To be more general you could allocated an
    array of size nColumnCount.

    Here is the change to function:

    HitTestEx(CPoint &point, int *col) const

    ....

    // Now find the column

    ASSERT( nColumnCount <= MAX_NUM_COLUMNS );
    int aColumnOrder[ MAX_NUM_COLUMNS ];

    VERIFY( ListView_GetColumnOrderArray(GetSafeHwnd(),
    nColumnCount,
    aColumnOrder) );

    for( colpos = 0; colpos < nColumnCount; colpos++ )
    {
    int colwidth = GetColumnWidth(aColumnOrder[ colpos ]);
    if( point.x >= rect.left
    && point.x <= (rect.left + colwidth ) )
    {
    if( col ) *col = aColumnOrder[ colpos ];
    return row;
    }
    rect.left += colwidth;
    }

    Reply
  • Stack & Heap Based Singleton

    Posted by Legacy on 05/17/1999 12:00am

    Originally posted by: Thierry Bensoussan

    The problem about Stack & Heap based singleton is discussed
    in Pattern Hatching.

    Although the use of a static member seems to be cleaner,
    this solution is not usable in a multi-threaded environnement
    where several threads can call the Instance() method
    concurently.

    In this context, the only right solution seems to be the one
    using a static pointer to the Singleton with a "Destroyer"
    inner class for memory management as described in
    "Pattern Hatching".

    However if you're not in a multi-threaded environnement, the
    static instance solution seems right.

    Reply
  • Zero based GetTopIndex

    Posted by Legacy on 03/15/1999 12:00am

    Originally posted by: Anthony Wong

    When looping through the visible rows, you should use "<" instead of "<=" since GetTopIndex() is zero based while GetItemCount() and GetCountPerPage() is not.

    Reply
  • SendMessage API for VB5

    Posted by Legacy on 01/22/1999 12:00am

    Originally posted by: Vilasack Phothisan

    So how would I do this in VB?

    Reply
  • detecting column index of item clicked

    Posted by Legacy on 11/30/1998 12:00am

    Originally posted by: Rob Tessier

    I believe you need to check for extended styles and not regular window
    styles to see if you list ctrl is in report mode.

    Is this a typo?

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

Top White Papers and Webcasts

  • Microsoft® Office 365 is a top choice for enterprises that want a cloud–based suite of productivity collaboration applications. With Office 365, you get access to Microsoft™ Office solutions practically anytime, anywhere, on virtually any device. It's a great option for current Microsoft users who can now build on their experience with Microsoft™ solutions while enjoying the flexibility of a cloud-based delivery. But even organizations with no previous investment in Microsoft will find that …

  • Like many roles in the C-Suite, the CIO role is also changing. Its impact and control have been circumvented by cloud computing, the consumerization of IT, and employees that now have unprecedented access to technology. The role of the CIO is at a critical juncture. For some CIOs, the changing landscape reduces their scope of influence. For others, it means unprecedented opportunity. This eBook explores the changes that CIOs are experiencing today and how these executives can leverage their expertise to help …

Most Popular Programming Stories

More for Developers

RSS Feeds

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