wxListCtrl::HitTest() does not account for header [wxMSW] (Issue #22239)

42 views
Skip to first unread message

PB

unread,
Mar 28, 2022, 1:12:12 PM3/28/22
to wx-...@googlegroups.com, Subscribed

Describe the bug
When the mouse cursor is over wxListCtrl header (i.e., not over any item), its HitTest() with flags set to wxLIST_HITTEST_ONITEM returns 0 instead of expected wxNOT_FOUND. All other items incl. 0 are reported correctly.

Patch or snippet allowing to reproduce the problem

diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp
index 4b2aae9e574a..9932c24d7f5b 100644
--- a/samples/listctrl/listtest.cpp
+++ b/samples/listctrl/listtest.cpp
@@ -122,6 +122,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
 
     EVT_MENU(LIST_SET_ITEMS_COUNT, MyFrame::OnSetItemsCount)
 
+    EVT_MENU(LIST_HIT_TEST, MyFrame::OnHitTest)
     EVT_MENU(LIST_GOTO, MyFrame::OnGoTo)
     EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast)
     EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
@@ -226,6 +227,7 @@ MyFrame::MyFrame(const wxString& title)
     menuView->Append(LIST_SET_ITEMS_COUNT, "Set &number of items");
 
     wxMenu *menuList = new wxMenu;
+    menuList->Append(LIST_HIT_TEST, "Demonstrate HitTest() Bug\tCtrl-B");
     menuList->Append(LIST_GOTO, "&Go to item #3\tCtrl-3");
     menuList->Append(LIST_FOCUS_LAST, "&Make last item current\tCtrl-L");
     menuList->Append(LIST_TOGGLE_FIRST, "To&ggle first item\tCtrl-G");
@@ -379,6 +381,18 @@ void MyFrame::OnCheckVisibility(wxCommandEvent& WXUNUSED(event))
         wxLogMessage( "Line 9 is not visible" );
 }
 
+void MyFrame::OnHitTest(wxCommandEvent& WXUNUSED(event))
+{
+    const wxPoint mousePosClient = m_listCtrl->ScreenToClient(wxGetMousePosition());
+    int           hitTestFlags   = wxLIST_HITTEST_ONITEM;
+    const long    itemIdx        = m_listCtrl->HitTest(mousePosClient, hitTestFlags);
+
+    if ( itemIdx == wxNOT_FOUND )
+        wxLogMessage("Mouse is not over an item");
+    else
+        wxLogMessage("Mouse is over an item with index %ld", itemIdx);
+}
+
 void MyFrame::OnGoTo(wxCommandEvent& WXUNUSED(event))
 {
     if ( m_listCtrl->IsEmpty() )
diff --git a/samples/listctrl/listtest.h b/samples/listctrl/listtest.h
index 9db71c27c9d7..80033653674c 100644
--- a/samples/listctrl/listtest.h
+++ b/samples/listctrl/listtest.h
@@ -119,7 +119,7 @@ class MyFrame: public wxFrame
     void OnCheckVisibility(wxCommandEvent& event);
     void OnSetItemsCount(wxCommandEvent& event);
 
-
+    void OnHitTest(wxCommandEvent& event);
     void OnGoTo(wxCommandEvent& event);
     void OnFocusLast(wxCommandEvent& event);
     void OnToggleFirstSel(wxCommandEvent& event);
@@ -210,6 +210,7 @@ enum
     LIST_SMALL_VIRTUAL_VIEW,
     LIST_SET_ITEMS_COUNT,
 
+    LIST_HIT_TEST,
     LIST_DESELECT_ALL,
     LIST_SELECT_ALL,
     LIST_DELETE_ALL,

To Reproduce
Run the patched sample, put the mouse cursor over a non-empty list control column header, press <Ctrl+B> and observe what gets written in the message log.

Platform and version information

  • wxWidgets version you use: Current GIT master
  • wxWidgets port you use: wxMSW
  • OS and its version: Windows 10.0.19044.1586

I checked the code and it seems that ListView_HitTest() does that, returning in pinfo 0 for iItem and LVHT_ONITEM in flags. Just to make sure, I checked the translated screen-to-client mouse coordinates and list control's client area using raw WinAPI but it was the same. But there must be some issue, I am not just seeing it ATM.

FWIW, wxListCtrl::GetItemRect() returns correct coordinates for item 0, i.e., offset by the header.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239@github.com>

VZ

unread,
Mar 29, 2022, 3:04:53 PM3/29/22
to wx-...@googlegroups.com, Subscribed

Sorry, didn't have time to test it yet, but if it's really a bug in ListView_HitTest(), we could perhaps check if it returns 0 and call it again without LVHT_ONITEM in this case and check if it returns -1 then and return the correct value from our function?


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239/1082264940@github.com>

PB

unread,
Mar 29, 2022, 4:29:29 PM3/29/22
to wx-...@googlegroups.com, Subscribed

I am sorry, but I do not understand. LVHITTESTINFO.flags appears to be only for receiving the result of the hit test (I wrote it confusingly in the issue and patch), not passing it to ListView_HitTest()? I find the official documentation for this variable rather confusing.

Just to make sure, I will test this with pure Win32 application soon but I do not expect to get different results.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239/1082343481@github.com>

VZ

unread,
Mar 29, 2022, 5:55:00 PM3/29/22
to wx-...@googlegroups.com, Subscribed

Sorry, I was indeed confused by the line hitTestFlags = wxLIST_HITTEST_ONITEM; above and thought it was an input/output flag, but it's output-only, of course.

So the only workaround I can finally suggest is even uglier: for the item 0, we'd need to check if we have the header and then compare y coordinate with the header height. We already have code in IsVisible() getting this height, so doing this should be relatively straightforward.

It's pretty strange that I could find nobody else complaining about this, but I really don't see what could we possibly be doing wrong here, the code in HitTest() is relatively trivial.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239/1082409304@github.com>

PB

unread,
Mar 30, 2022, 4:53:24 AM3/30/22
to wx-...@googlegroups.com, Subscribed

I agree that it would be surprising if there was such an obvious bug in ListView_HitTest(). However, the code in wxListCtrl::IsVisible() correcting the result of the API call when the header is present may indicate that something may be odd here.

I find interesting that when I bind wxEVT_MOTION and wxEVT_LEAVE_WINDOW to a wxListCtrl in report mode; motion events are not received when the mouse cursor is over the header and wxEVT_LEAVE_WINDOW is received when I move the mouse cursor from the item area to the header. So maybe the issue is rarely observed because people usually hit test from the listview events and hence do not use coordinates outside the item area?

FWIW, I tried to reproduce the issue with pure Win32 application: https://gist.github.com/PBfordev/27e6186e101c89c49e744cd3a3699e64
The result is the same. Also, ListView_GetOrigin() and ListView_GetViewRect() return 0 for the top coordinate, so does ListView_GetItemRect() for item 0...

But I may be still doing something wrong, so for now I will not attempt to "fix" the issue (in a different form present also on MacOS) and wait for someone else hopefully looking into this to either confirm the issue or show where I am wrong.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239/1082804837@github.com>

Igor Korot

unread,
Mar 30, 2022, 7:51:51 AM3/30/22
to wx-dev, Subscribed
Hi,
Maybe send this to one of the MS forums to review?
Or file a bug with them...

Thank you.


--
You received this message because you are subscribed to the Google Groups "wx-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wx-dev+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wx-dev/wxWidgets/wxWidgets/issues/22239/1082804837%40github.com.

VZ

unread,
Mar 30, 2022, 8:18:48 AM3/30/22
to wx-...@googlegroups.com, Subscribed

I forgot about scrolling, but this makes the workaround even less appealing (although not necessarily much more complicated, we'd just need to check for the returned item being == GetTopItem() instead of 0).

The mouse events problem is another bug, of course... It's easy to understand this one, at least: as the header window is a different window (HWND), the listview window doesn't get the mouse events when the mouse is over it. So to fix this we need to catch mouse messages for the header window and convert them to the listview events. This is certainly doable but would require more work than I'm personally able to spend on it.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239/1083069214@github.com>

Nico Rieck

unread,
Aug 28, 2026, 12:28:42 PM (3 days ago) Aug 28
to wx-...@googlegroups.com, Subscribed
gix left a comment (wxWidgets/wxWidgets#22239)

I was curious how Microsoft's MMC does this, since its context menus don't open for the header. They do a ChildWindowFromPoint(pt, CWP_SKIPINVISIBLE) and if the result is different from the list's HWND the message is ignored.

Interestingly LVHITTESTINFO.flags also seems to return an undocumented flag 0x200 when a header item is hit.


Reply to this email directly, view it on GitHub, or unsubscribe.

Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239/5455040653@github.com>

PB

unread,
Aug 28, 2026, 1:57:51 PM (3 days ago) Aug 28
to wx-...@googlegroups.com, Subscribed
PBfordev left a comment (wxWidgets/wxWidgets#22239)

Thanks @gix! Using ChildWindowFromPointEx() seems to work well.


Reply to this email directly, view it on GitHub, or unsubscribe.

Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22239/5455942641@github.com>

VZ

unread,
Aug 30, 2026, 7:23:03 PM (18 hours ago) Aug 30
to wx-...@googlegroups.com, Subscribed

Closed #22239 as completed via 375889c.


Reply to this email directly, view it on GitHub, or unsubscribe.

Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issue/22239/issue_event/30249432160@github.com>

Reply all
Reply to author
Forward
0 new messages