Virtual Developer Workshop: Containerized Development with Docker

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


  • Missing licencing information

    Posted by freds72 on 11/16/2010 07:48pm

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

  • Misses the last row

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

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

  • help me!

    Posted by Legacy on 08/05/2002 07: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!

  • Also can use SubItemHitTest

    Posted by Legacy on 05/31/2000 07: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)
    lvhti.pt = point;

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

    • Does not work

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

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

  • If I don't use mouse

    Posted by Legacy on 08/03/1999 07: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 12:53pm

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

    • And if there is no click?

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

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

  • Fix so that hit test works with reordered columns

    Posted by Legacy on 07/05/1999 07: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.

    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(),
    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;

  • Stack & Heap Based Singleton

    Posted by Legacy on 05/17/1999 07: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

    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.

  • Zero based GetTopIndex

    Posted by Legacy on 03/15/1999 08: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.

  • SendMessage API for VB5

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

    Originally posted by: Vilasack Phothisan

    So how would I do this in VB?

  • detecting column index of item clicked

    Posted by Legacy on 11/30/1998 08: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?

  • You must have javascript enabled in order to post comments.

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

Most Popular Programming Stories

More for Developers

RSS Feeds

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