예제 #1
0
        // Returns the previous sibling element in the raw hierarchy.
        // Peripheral controls have always negative values.
        // Returns null is no previous
        internal override ProxySimple GetPreviousSibling(ProxySimple child)
        {
            GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID);

            if (groupInfo)
            {
                int [] items   = groupInfo._items;
                int    current = child._item;

                // The subset link has an index that is one past the list items
                // If we are on that then the previous is the last item in the items array.
                if (_isComctrlV6OnOsVerV6orHigher && current == groupInfo._count)
                {
                    int index = items [groupInfo._count - 1];

                    return(CreateListViewItem(index));
                }

                // find the index of the current lvitem
                int prevLocation = groupInfo.IndexOf(current) - 1;

                if (prevLocation <= -2)
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                if (prevLocation >= 0)
                {
                    return(CreateListViewItem(items [prevLocation]));
                }
            }

            return(null);
        }
        // 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);
        }
예제 #3
0
        // Returns the last child element in the raw hierarchy.
        internal override ProxySimple GetLastChild()
        {
            // return last item in this group
            GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID);

            // List view groups in vista can have an extra link at the end that says
            // something like "show all 11 items...".  If one exists expose it as the last child.
            if (_isComctrlV6OnOsVerV6orHigher)
            {
                NativeMethods.LVGROUP_V6 group = new NativeMethods.LVGROUP_V6();
                group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6)));
                group.iGroupID  = _groupID;
                group.mask      = NativeMethods.LVGF_STATE;
                group.stateMask = NativeMethods.LVGS_SUBSETED;

                // Note: return code of GetGroupInfo() is not reliable.
                XSendMessage.GetGroupInfo(_hwnd, ref group); // ignore return code.

                // if we are not subseted then the last item is a regular listitem so
                // it is ok to fall through and let that be created.  Otherwise we need to
                // create the subset link proxy.
                if ((group.state & NativeMethods.LVGS_SUBSETED) != 0)
                {
                    int [] items = groupInfo._items;
                    if (groupInfo._count <= 0 || groupInfo._count > items.Length)
                    {
                        return(null);
                    }

                    int index = items [groupInfo._count - 1];
                    return(CreateGroupSubsetLink(index + 1));
                }
            }


            if (groupInfo)
            {
                int [] items = groupInfo._items;
                if (groupInfo._count <= 0 || groupInfo._count > items.Length)
                {
                    return(null);
                }

                int index = items [groupInfo._count - 1];

                return(CreateListViewItem(index));
            }

            return(null);
        }
예제 #4
0
        // This method returns the count of either columns or rows
        // in the Grid.
        static private int GetCountOfItemsInDimension(IntPtr hwnd, int groupID, IsNewItemInDimension comparer)
        {
            // Algorithm:
            // Get the rect of the item.
            // Compare it using provided "comparer" with the previously obtained rect of the previous item in the grid
            // if comparer returns New increase the count
            int itemsCount = 0;

            GroupManager.GroupInfo groupInfo = GetGroupInfo(hwnd, groupID);

            if (groupInfo)
            {
                int [] items = groupInfo._items;
                NativeMethods.Win32Rect rc;
                NativeMethods.Win32Rect rcNext;

                // get coordinates of the first item in the grid
                if (WindowsListView.GetItemRect(hwnd, items[0], NativeMethods.LVIR_BOUNDS, out rc))
                {
                    NewItemInDimension result = NewItemInDimension.New;

                    itemsCount++; // at least one exist
                    for (int i = 1; result != NewItemInDimension.Stop && i < groupInfo._count; i++)
                    {
                        if (!WindowsListView.GetItemRect(hwnd, items[i], NativeMethods.LVIR_BOUNDS, out rcNext))
                        {
                            // Fail to get rc, makes no sense to continue
                            System.Diagnostics.Debug.Assert(false, "GetCountOfItemsInDimension: failed to get item rect");
                            return(0);
                        }

                        result = comparer(rc, rcNext);
                        if (result == NewItemInDimension.New)
                        {
                            // found a change in the rect
                            // we either have a new column or new raw
                            itemsCount++;

                            // update the rc with the new coordinates
                            rc = rcNext;
                        }
                    }
                }

                return(itemsCount);
            }

            return(-1);
        }
예제 #5
0
        // Returns the first child element in the raw hierarchy.
        internal override ProxySimple GetFirstChild()
        {
            // return first item in this group
            GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID);

            if (groupInfo)
            {
                int [] items = groupInfo._items;
                int    index = items [0];

                return(CreateListViewItem(index));
            }

            return(null);
        }
예제 #6
0
        // Returns the next sibling element in the raw hierarchy.
        // Peripheral controls have always negative values.
        // Returns null if no next child
        internal override ProxySimple GetNextSibling(ProxySimple child)
        {
            GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID);

            if (groupInfo)
            {
                int [] items   = groupInfo._items;
                int    current = child._item;

                // find the index of the current lvitem
                int nextLocation = groupInfo.IndexOf(current) + 1;  //Array.IndexOf(items, current) + 1;

                if (nextLocation <= 0)
                {
                    // No more siblings
                    return(null);
                }

                if (nextLocation < groupInfo._count)
                {
                    return(CreateListViewItem(items [nextLocation]));
                }

                // List view groups in vista can have an extra link at the end that says
                // somthing like "show all 11 items..."
                if (_isComctrlV6OnOsVerV6orHigher && nextLocation == groupInfo._count)
                {
                    NativeMethods.LVGROUP_V6 group = new NativeMethods.LVGROUP_V6();
                    group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6)));
                    group.iGroupID  = _groupID;
                    group.mask      = NativeMethods.LVGF_STATE;
                    group.stateMask = NativeMethods.LVGS_SUBSETED;

                    // Note: return code of GetGroupInfo() is not reliable.
                    XSendMessage.GetGroupInfo(_hwnd, ref group); // ignore return code.

                    // 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.
                    if ((group.state & NativeMethods.LVGS_SUBSETED) != 0)
                    {
                        return(CreateGroupSubsetLink(items [groupInfo._count - 1] + 1));
                    }
                }
            }

            return(null);
        }
예제 #7
0
        // Grid.GetCell implementation for detail mode
        private IRawElementProviderSimple GetCellInDetailMode(int row, int column)
        {
            // Note: column can be used as it is
            // row corresponds to the index into the array of items that belong to current group
            GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID);

            if (groupInfo)
            {
                int           lvitemIndex = groupInfo._items [row];
                ProxyFragment lvItem      = CreateListViewItem(lvitemIndex);

                return(new ListViewSubItem(_hwnd, lvItem, column, lvitemIndex));
            }

            return(null);
        }
예제 #8
0
        // 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);
        }
예제 #9
0
        // utility method returning object describing current group
        static internal GroupManager.GroupInfo GetGroupInfo(IntPtr hwnd, int groupID)
        {
            GroupManager.GroupInfo groupInfo = GroupManager.GroupInfo.Null;

            // if groupmanager is not available GetManager(hwnd)
            // will raise needed event
            GroupManager manager = WindowsListView._groupsCollection [hwnd];

            groupInfo = manager.GetGroupInfo(groupID);
            if (!groupInfo)
            {
                // LV control did not raise the needed event
                // alexsn @


                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            return(groupInfo);
        }
        // utility method returning object describing current group
        static internal GroupManager.GroupInfo GetGroupInfo(IntPtr hwnd, int groupID)
        {
            GroupManager.GroupInfo groupInfo = GroupManager.GroupInfo.Null;

            // if groupmanager is not available GetManager(hwnd)
            // will raise needed event
            GroupManager manager = WindowsListView._groupsCollection [hwnd];

            groupInfo = manager.GetGroupInfo(groupID);
            if (!groupInfo)
            {
                // LV control did not raise the needed event
                // Microsoft - We may want to consider raising the event here
                // The M7 work on checking if LE is valid however is the better way of going
                //  RemoveGroupAndRaiseLogicalChangedEvent(_hwnd);
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            return(groupInfo);
        }
예제 #11
0
        // retrieve number of rows in the group
        static private int GetRowCount(IntPtr hwnd, int groupID)
        {
            if (WindowsListView.IsDetailMode(hwnd))
            {
                // When lv in Detail mode (with items shown in groups)
                // each lvitem will live in their own row
                // we need to detect how many items belong to the group,
                // this would correspond to the number of rows
                GroupManager.GroupInfo groupInfo = GetGroupInfo(hwnd, groupID);

                if (groupInfo)
                {
                    return(groupInfo._count);
                }

                // Good place to send Grid Invalid event
                return(-1);
            }

            return(GetCountOfItemsInDimension(hwnd, groupID, new IsNewItemInDimension(IsNewRow)));
        }
예제 #12
0
        // Grid.GetCell implementation for lv that is not in detail mode
        private IRawElementProviderSimple GetCellInOtherModes(int row, int column, int maxColumn)
        {
            // Convert row, column into the index into the array of items that belong to
            // current group
            int indexIntoArray = row * maxColumn + column;

            GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID);

            if (!groupInfo)
            {
                return(null);
            }

            if (indexIntoArray >= groupInfo._count)
            {
                // Return an empty cell
                return(new EmptyGridItem(row, column, this));
            }

            // return cell
            return(CreateListViewItem(groupInfo._items [indexIntoArray]));
        }
예제 #13
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);
        }