//------------------------------------------------------ // // 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); }