protected OlvListViewHitTestInfo LowLevelHitTest(int x, int y)
{
// If it's not even in the control, don't bother with anything else
if (!this.ClientRectangle.Contains(x, y))
return new OlvListViewHitTestInfo(null, null, 0, null);
//if (Control.ModifierKeys == Keys.Control)
// System.Diagnostics.Debugger.Break();
// Call the native hit test method, which is a little confusing.
NativeMethods.LVHITTESTINFO lParam = new NativeMethods.LVHITTESTINFO();
lParam.pt_x = x;
lParam.pt_y = y;
int index = NativeMethods.HitTest(this, ref lParam);
// Setup the various values we need to make our hit test structure
bool isGroupHit = (lParam.flags & (int)HitTestLocationEx.LVHT_EX_GROUP) != 0;
OLVListItem hitItem = isGroupHit || index == -1 ? null : this.GetItem(index);
OLVListSubItem subItem = (this.View == View.Details && hitItem != null) ? hitItem.GetSubItem(lParam.iSubItem) : null;
// Figure out which group is involved in the hit test. This is a little complicated:
// If the list is virtual:
// - the returned value is list view item index
// - iGroup is the *index* of the hit group.
// If the list is not virtual:
// - iGroup is always -1.
// - if the point is over a group, the returned value is the *id* of the hit group.
// - if the point is not over a group, the returned value is list view item index.
OLVGroup group = null;
if (this.ShowGroups && this.OLVGroups != null) {
if (this.VirtualMode) {
group = lParam.iGroup >= 0 && lParam.iGroup < this.OLVGroups.Count ? this.OLVGroups[lParam.iGroup] : null;
} else {
if (isGroupHit) {
foreach (OLVGroup olvGroup in this.OLVGroups) {
if (olvGroup.GroupId == index) {
group = olvGroup;
break;
}
}
}
}
}
OlvListViewHitTestInfo olvListViewHitTest = new OlvListViewHitTestInfo(hitItem, subItem, lParam.flags, group);
// System.Diagnostics.Debug.WriteLine(String.Format("HitTest({0}, {1})=>{2}", x, y, olvListViewHitTest));
return olvListViewHitTest;
}