Exemple #1
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        // retrieve bounding rectangle of the listview checkbox
        internal static NativeMethods.Win32Rect ListViewCheckBoxRect(IntPtr hwnd, int item)
        {
            //  Rare special case
            if (WindowsListView.FullRowSelect(hwnd) && WindowsListView.IsDetailMode(hwnd))
            {
                // Get listview window rect
                NativeMethods.Win32Rect controlRectangle = NativeMethods.Win32Rect.Empty;

                if (!Misc.GetWindowRect(hwnd, ref controlRectangle))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                // BOUNDS == SELECTBOUNDS, hence cannot rely on them
                // will rely on the ICON or LABEL
                // Try icon first since it is the closest to the checkbox
                NativeMethods.Win32Rect rc;

                if ((WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_ICON, out rc) && rc.left != rc.right) || (WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_LABEL, out rc) && rc.left != rc.right))
                {
                    int right = controlRectangle.left + (rc.left - controlRectangle.left);

                    return(new NativeMethods.Win32Rect(controlRectangle.left, rc.top, right, rc.bottom));
                }
            }
            else
            {
                // Very common, simple case
                NativeMethods.Win32Rect wholeItem;

                if (!WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_BOUNDS, out wholeItem))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                NativeMethods.Win32Rect selectable;

                if (!WindowsListView.GetItemRect(hwnd, item, NativeMethods.LVIR_SELECTBOUNDS, out selectable))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                if (Misc.IsControlRTL(hwnd))
                {
                    return(new NativeMethods.Win32Rect(selectable.right, wholeItem.top, wholeItem.right, wholeItem.bottom));
                }
                else
                {
                    return(new NativeMethods.Win32Rect(wholeItem.left, wholeItem.top, selectable.left, wholeItem.bottom));
                }
            }

            return(NativeMethods.Win32Rect.Empty);
        }
            internal NativeMethods.Win32Rect CalculateRectNoHeader()
            {
                NativeMethods.Win32Rect rcLv = NativeMethods.Win32Rect.Empty;

                if (!Misc.GetWindowRect(_hwnd, ref rcLv))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                // set top to the top coordinate of the first item
                NativeMethods.Win32Rect item;
                WindowsListView.GetItemRect(_hwnd, _items[0], NativeMethods.LVIR_BOUNDS, out item);

                NativeMethods.Win32Rect groupRc;
                groupRc.top = item.top;

                // left coordinate defined by the left coordinate of the listview
                groupRc.left = rcLv.left;

                int count = Count;

                // bottom defined by the bottom coordinate of the last item
                if (count > 1)
                {
                    // get the rect of the last item in the group
                    WindowsListView.GetItemRect(_hwnd, _items[count - 1], NativeMethods.LVIR_BOUNDS, out item);
                }

                groupRc.bottom = item.bottom;

                // right coordinate defined by lv.right
                groupRc.right = rcLv.right;

                // when vertical scrollbar is present take it into account
                if (WindowScroll.Scrollable(_hwnd, NativeMethods.SB_VERT))
                {
                    NativeMethods.Win32Rect rc = GetScrollbarRect();
                    int width = rc.right - rc.left;

                    if (Misc.IsControlRTL(_hwnd))
                    {
                        // Right to left mirroring style
                        groupRc.left += width;
                    }
                    else
                    {
                        groupRc.right -= width;
                    }
                }

                return(groupRc);
            }
        // 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);
        }
        // Obtain clickable point on the listviewitem
        // in the case when one doesnot exist return false
        private bool GetListviewitemClickablePoint(out NativeMethods.Win32Point clickPoint)
        {
            // When this method is called, lv was already scrolled vertically
            // hence item is visible veritcally
            clickPoint.x = clickPoint.y = 0;

            NativeMethods.Win32Rect itemRectangle;

            // Obtain rectangle
            if (!WindowsListView.GetItemRect(_hwnd, _item, NativeMethods.LVIR_LABEL, out itemRectangle))
            {
                return(false);
            }

            if (WindowsListView.IsDetailMode(_hwnd) && !WindowsListView.FullRowSelect(_hwnd))
            {
                // LVS_REPORT - possible that we may need to scroll horizontaly
                //
                NativeMethods.Win32Point pt = new NativeMethods.Win32Point(itemRectangle.left, 0);

                if (!Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref pt, 1))
                {
                    return(false);
                }

                // In client coordinates, hence negative indicates that item is to the left of lv client area
                if (pt.x < 0)
                {
                    ((IScrollItemProvider)this).ScrollIntoView();

                    if (!WindowsListView.GetItemRect(_hwnd, _item, NativeMethods.LVIR_LABEL, out itemRectangle))
                    {
                        return(false);
                    }
                }
            }

            clickPoint.x = Math.Min((itemRectangle.left + 5), (itemRectangle.left + itemRectangle.right) / 2);
            clickPoint.y = (itemRectangle.top + itemRectangle.bottom) / 2;
            return(true);
        }
            //------------------------------------------------------
            //
            //  IComparer
            //
            //------------------------------------------------------

            #region IComparer

            int IComparer.Compare(object x, object y)
            {
                int item1 = (int)x;
                int item2 = (int)y;

                // get the rect of 2 items
                NativeMethods.Win32Rect rc1;
                WindowsListView.GetItemRect(_hwnd, item1, NativeMethods.LVIR_BOUNDS, out rc1);

                NativeMethods.Win32Rect rc2;
                WindowsListView.GetItemRect(_hwnd, item2, NativeMethods.LVIR_BOUNDS, out rc2);


                // compare rectangles
                if (rc1.left < rc2.left || rc1.top < rc2.top)
                {
                    return(-1);
                }
                else if (rc1.left != rc2.left || rc1.top != rc2.top)
                {
                    return(1);
                }
                return(0);
            }