// 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);
            }
Ejemplo n.º 3
0
        //------------------------------------------------------
        //
        //  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);
        }
Ejemplo n.º 4
0
        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;
        }