// retrieve lvitem column position in the Grid // To be called only when Group is enabled private int GetItemColumnPositionInGroup() { // get id of the group to which this item belongs int groupID = GetGroupID(_hwnd, _item); if (groupID != -1) { // get position of this lvitem within the array of all items in the group GroupManager.GroupInfo groupInfo = WindowsListViewGroup.GetGroupInfo(_hwnd, groupID); if (groupInfo) { int position = groupInfo.IndexOf(_item); //Array.IndexOf(groupInfo._items, _item); if (position != -1) { // number of columns in the grid int columnCount = WindowsListViewGroup.GetColumnCountExternal(_hwnd, groupID); // item's row position int itemRowPosition = position / columnCount; // item's column position return(position - (itemRowPosition * columnCount)); } } } return(-1); }
internal unsafe NativeMethods.Win32Rect GetGroupRect() { NativeMethods.Win32Rect rect = new NativeMethods.Win32Rect(); bool isCollapsed = WindowsListViewGroup.IsCollapsed(_hwnd, _groupID); rect.top = isCollapsed ? NativeMethods.LVGGR_HEADER : NativeMethods.LVGGR_GROUP; XSendMessage.XSend(_hwnd, NativeMethods.LVM_GETGROUPRECT, new IntPtr(_groupID), new IntPtr(&rect), Marshal.SizeOf(rect.GetType())); Misc.MapWindowPoints(_hwnd, IntPtr.Zero, ref rect, 2); return(rect); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // get focused element internal static ProxySimple GetFocusInGroup(IntPtr hwnd, ProxyFragment parent) { int index = WindowsListView.GetItemNext(hwnd, -1, NativeMethods.LVNI_FOCUSED); if (index != -1) { // get id of the group to which item belongs NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6(); item.mask = NativeMethods.LVIF_GROUPID; item.iItem = index; if (XSendMessage.GetItem(hwnd, ref item)) { WindowsListViewGroup group = new WindowsListViewGroup(hwnd, parent, item.iGroupID); return(new ListViewItem(hwnd, group, index)); } } else { // if none of the items have focus see if the focus is on the subset link // this only exists in v6 comctrl on vista or later. if (Misc.IsComctrlV6OnOsVerV6orHigher(hwnd)) { int groupIndex = (int)Misc.ProxySendMessage(hwnd, NativeMethods.LVM_GETFOCUSEDGROUP, IntPtr.Zero, IntPtr.Zero); // need to convert the item id to a group id NativeMethods.LVGROUP_V6 groupInfo = new NativeMethods.LVGROUP_V6(); groupInfo.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); groupInfo.mask = NativeMethods.LVGF_GROUPID; unsafe { bool lresult = XSendMessage.XSend(hwnd, NativeMethods.LVM_GETGROUPINFOBYINDEX, new IntPtr(groupIndex), new IntPtr(&groupInfo), Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); if (!lresult) { // no group for this item should never happen. return(null); } } int groupId = groupInfo.iGroupID; groupInfo.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); groupInfo.iGroupID = groupId; groupInfo.mask = NativeMethods.LVGF_STATE; groupInfo.stateMask = NativeMethods.LVGS_SUBSETLINKFOCUSED; // Note: return code of GetGroupInfo() is not reliable. XSendMessage.GetGroupInfo(hwnd, ref groupInfo); // ignore return code. if ((groupInfo.state & NativeMethods.LVGS_SUBSETLINKFOCUSED) != 0) { GroupManager.GroupInfo groupManagerInfo = GetGroupInfo(hwnd, groupId); int [] items = groupManagerInfo._items; if (groupManagerInfo._count <= 0 || groupManagerInfo._count >= items.Length) { return(null); } int sslIndex = items [groupManagerInfo._count - 1]; // The items array holds the list items in this group. If we have a subset link we // don't store it with the list items because it isn't really a list item. Instead we just // create the subset link proxy with an item index one more than the last index. WindowsListViewGroup group = new WindowsListViewGroup(hwnd, parent, groupId); return(group.CreateGroupSubsetLink(sslIndex + 1)); } else { return(new WindowsListViewGroup(hwnd, parent, groupId)); } } } return(null); }
internal override ProxySimple ElementProviderFromPoint (int x, int y) { // The header is a window on top of the client area. // If the point is the non client area, skip // Must return null if hit tested. if (PtInListViewHeader (x, y) || !PtInClientRect (_hwnd, x, y)) { return null; } // in the case of the lv in the group mode, return a group at point(x,y) if (IsGroupViewEnabled (_hwnd)) { _groupsCollection.EnsureCreation (_hwnd); // Let's locate the group that contains x,y GroupManager manager = WindowsListView._groupsCollection [_hwnd]; int length = manager.GroupCount (); for (int i = 0; i < length; i++) { NativeMethods.Win32Rect rc = manager.GetGroupRcByIndex (i); if (Misc.PtInRect(ref rc, x, y)) { // found a group where point belongs int groupID = manager.GetGroupIdByIndex (i); ProxyFragment group = new WindowsListViewGroup (_hwnd, this, groupID); return ProxyFragment.DrillDownFragment (group, x, y); } } } NativeMethods.LVHITTESTINFO_INTERNAL hitTest = WindowsListView.SubitemHitTest(_hwnd, new NativeMethods.Win32Point(x, y)); if (hitTest.iItem >= 0) { // create the item ProxyFragment item = CreateListViewItemOrStartMenuItem(this, hitTest.iItem); return ProxyFragment.DrillDownFragment (item, x, y); } else if (hitTest.flags == NativeMethods.LVHT_NOWHERE && IsDetailMode(_hwnd)) { // LVHT_NOWHERE means: The position is inside the list-view control's client window, but it is not over a list item. // The hit was in the non-client area of the ListView box, so adjust piont to get the point on a // sub-item to find which ListViewItem to create. There is not adjustment needed in the y-coordinate // spaces since ListView's do not apply a non-client area to the top or the bottom of items. Rect boundingRectangle = BoundingRectangle; int xAdjustment = UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CXBORDER) + UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CXFRAME); if (x - boundingRectangle.Left < xAdjustment) { x += xAdjustment; } else if (boundingRectangle.Left + boundingRectangle.Width - x < xAdjustment) { x -= xAdjustment; } hitTest = WindowsListView.SubitemHitTest(_hwnd, new NativeMethods.Win32Point(x, y)); if (hitTest.iItem >= 0) { // Since this original point was in the non-client area of the listview, the item being looked for // is the item not one of it's subitems, so just return the ListViewItem. return CreateListViewItemOrStartMenuItem(this, hitTest.iItem); } } // NOTE: Do not return this, since user might of specified point that belongs to the hwnd-control // that lives inside of the lv (e.g. header). If we return null UIAutomation will do the drilling return null; }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // get focused element internal static ProxySimple GetFocusInGroup (IntPtr hwnd, ProxyFragment parent) { int index = WindowsListView.GetItemNext(hwnd, -1, NativeMethods.LVNI_FOCUSED); if (index != -1) { // get id of the group to which item belongs NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6 (); item.mask = NativeMethods.LVIF_GROUPID; item.iItem = index; if (XSendMessage.GetItem(hwnd, ref item)) { WindowsListViewGroup group = new WindowsListViewGroup (hwnd, parent, item.iGroupID); return new ListViewItem (hwnd, group, index); } } else { // if none of the items have focus see if the focus is on the subset link // this only exists in v6 comctrl on vista or later. if (Misc.IsComctrlV6OnOsVerV6orHigher(hwnd)) { int groupIndex = (int)Misc.ProxySendMessage(hwnd, NativeMethods.LVM_GETFOCUSEDGROUP, IntPtr.Zero, IntPtr.Zero); // need to convert the item id to a group id NativeMethods.LVGROUP_V6 groupInfo = new NativeMethods.LVGROUP_V6(); groupInfo.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); groupInfo.mask = NativeMethods.LVGF_GROUPID; unsafe { bool lresult = XSendMessage.XSend(hwnd, NativeMethods.LVM_GETGROUPINFOBYINDEX, new IntPtr(groupIndex), new IntPtr(&groupInfo), Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); if (!lresult) { // no group for this item should never happen. return null; } } int groupId = groupInfo.iGroupID; groupInfo.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); groupInfo.iGroupID = groupId; groupInfo.mask = NativeMethods.LVGF_STATE; groupInfo.stateMask = NativeMethods.LVGS_SUBSETLINKFOCUSED; // Note: return code of GetGroupInfo() is not reliable. XSendMessage.GetGroupInfo(hwnd, ref groupInfo); // ignore return code. if ((groupInfo.state & NativeMethods.LVGS_SUBSETLINKFOCUSED) != 0) { GroupManager.GroupInfo groupManagerInfo = GetGroupInfo (hwnd, groupId); int [] items = groupManagerInfo._items; if (groupManagerInfo._count <= 0 || groupManagerInfo._count >= items.Length) { return null; } int sslIndex = items [groupManagerInfo._count - 1]; // The items array holds the list items in this group. If we have a subset link we // don't store it with the list items because it isn't really a list item. Instead we just // create the subset link proxy with an item index one more than the last index. WindowsListViewGroup group = new WindowsListViewGroup (hwnd, parent, groupId); return group.CreateGroupSubsetLink(sslIndex + 1); } else { return new WindowsListViewGroup (hwnd, parent, groupId); } } } return null; }