// perform a hit test on the specific point // POINT is in screen coordinates static internal NativeMethods.LVHITTESTINFO_INTERNAL SubitemHitTest (IntPtr hwnd, int item, NativeMethods.Win32Point pt) { // Allocate a local LVHITTESTINFO struct. NativeMethods.LVHITTESTINFO_INTERNAL hitTest = new NativeMethods.LVHITTESTINFO_INTERNAL (); // Set the point of interest. hitTest.pt = pt; hitTest.iItem = item; int result = -1; // convert to client if (Misc.MapWindowPoints(IntPtr.Zero, hwnd, ref hitTest.pt, 1)) { unsafe { // Send the LVM_SUBITEMHITTEST message to the list view owner process. // This is ok to do even for non LVS_REPORT listview, since in that case this // message will behaive like LVM_HITTEST if (Misc.IsComctrlV6OnOsVerV6orHigher(hwnd)) { NativeMethods.LVHITTESTINFO_V6 hitTestNative = new NativeMethods.LVHITTESTINFO_V6(hitTest); result = XSendMessage.XSendGetIndex(hwnd, NativeMethods.LVM_SUBITEMHITTEST, IntPtr.Zero, new IntPtr(&hitTestNative), Marshal.SizeOf(hitTestNative.GetType())); hitTest.flags = hitTestNative.flags; hitTest.iItem = hitTestNative.iItem; hitTest.iGroup = hitTestNative.iGroup; } else { NativeMethods.LVHITTESTINFO hitTestNative = new NativeMethods.LVHITTESTINFO(hitTest); result = XSendMessage.XSendGetIndex(hwnd, NativeMethods.LVM_SUBITEMHITTEST, IntPtr.Zero, new IntPtr(&hitTestNative), Marshal.SizeOf(hitTestNative.GetType())); hitTest.flags = hitTestNative.flags; hitTest.iItem = hitTestNative.iItem; } } } if (result == -1) { hitTest.iSubItem = hitTest.iItem = -1; } return hitTest; }
// Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint (int x, int y) { NativeMethods.Win32Point pt = new NativeMethods.Win32Point (x, y); NativeMethods.LVHITTESTINFO_INTERNAL hitTest = WindowsListView.SubitemHitTest (_hwnd, pt); if ((hitTest.flags & NativeMethods.LVHT_EX_GROUP_HEADER) != 0) { return this; } if ((hitTest.flags & NativeMethods.LVHT_ONITEM) != 0 && hitTest.iItem >= 0) { // create the item return new ListViewItem (_hwnd, this, hitTest.iItem); } // If we did not land on an item we may be at a subset link these only exist // in v6 comctrl and vista or later. if (_isComctrlV6OnOsVerV6orHigher) { // Allocate a local LVHITTESTINFO struct. NativeMethods.LVHITTESTINFO_V6 hitTestNative = new NativeMethods.LVHITTESTINFO_V6(hitTest); unsafe { XSendMessage.XSendGetIndex(_hwnd, NativeMethods.LVM_HITTEST, new IntPtr(-1), new IntPtr(&hitTestNative), Marshal.SizeOf(hitTestNative.GetType())); } if ((hitTestNative.flags & NativeMethods.LVHT_EX_GROUP_SUBSETLINK) != 0) { GroupManager.GroupInfo groupInfo = GetGroupInfo (_hwnd, ID); int [] items = groupInfo._items; if (groupInfo._count <= 0 || groupInfo._count > items.Length) { return null; } int index = items [groupInfo._count - 1]; return CreateGroupSubsetLink(index + 1); } } return this; }