Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / UIAutomation / Win32Providers / MS / Internal / AutomationProxies / WindowsListViewItem.cs / 1 / WindowsListViewItem.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Win32 ListView Item proxy // // History: // Jean-Francois Peyroux, alexsn - Created (in DotNet) // 2003/08/11 - alexsn Updated for WCP // //--------------------------------------------------------------------------- // PRESHARP: In order to avoid generating warnings about unknown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 using System; using System.ComponentModel; using System.Windows.Automation; using System.Windows.Automation.Provider; using System.Runtime.InteropServices; using System.Windows; using Accessibility; using MS.Win32; namespace MS.Internal.AutomationProxies { internal class ListViewItem : ProxyFragment, IInvokeProvider, ISelectionItemProvider, IValueProvider, IGridItemProvider, IScrollItemProvider { // ----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors internal ListViewItem (IntPtr hwnd, ProxyFragment parent, int item) : base (hwnd, parent, item) { // Set the strings to return properly the properties. if (WindowsListView.IsDetailMode(hwnd)) { _cControlType = ControlType.DataItem; } else { _cControlType = ControlType.ListItem; } _fHasPersistentID = false; _fIsKeyboardFocusable = true; _isComctrlV6OnOsVerV6orHigher = Misc.IsComctrlV6OnOsVerV6orHigher(hwnd); } #endregion Constructos //------------------------------------------------------ // // Patterns Implementation // //----------------------------------------------------- #region ProxySimple Interface // Returns a pattern interface if supported. internal override object GetPatternProvider (AutomationPattern iid) { if (iid == InvokePattern.Pattern && WindowsListView.ListViewInvokable(_hwnd)) { return this; } if (iid == SelectionItemPattern.Pattern) { return this; } if (iid == ValuePattern.Pattern && WindowsListView.ListViewEditable (_hwnd)) { return this; } if (iid == GridItemPattern.Pattern && IsImplementingGrid (_hwnd)) { return this; } if (iid == TogglePattern.Pattern && IsItemWithCheckbox(_hwnd, _item)) { return CreateListViewItemCheckbox(); } if (iid == ScrollItemPattern.Pattern && WindowScroll.IsScrollable(_hwnd)) { return this; } return null; } // Gets the bounding rectangle for this element internal override Rect BoundingRectangle { get { NativeMethods.Win32Rect itemRectangle = NativeMethods.Win32Rect.Empty; Rect boundingRectangle = Rect.Empty; // If we have a listview that could support group view we need to use a diferent method // to get the builnding rect. If anything fails trying this way just fall back to the old way // of doing things. if (_isComctrlV6OnOsVerV6orHigher) { itemRectangle.left = NativeMethods.LVIR_BOUNDS; WindowsListViewGroup windowsListViewGroup = _parent as WindowsListViewGroup; if (windowsListViewGroup != null) { // The group might have been destroyed by an event WindowsListView._groupsCollection.EnsureCreation (_hwnd); GroupManager manager = WindowsListView._groupsCollection[_hwnd]; int [] groupIds = manager.GetGroupIds (); // find the index for this group int index; for (index = 0; index < groupIds.Length && windowsListViewGroup.ID != groupIds[index]; index++); if (index >= groupIds.Length) { return boundingRectangle; } NativeMethods.LVITEMINDEX ii = new NativeMethods.LVITEMINDEX(); ii.iGroup = index; ii.iItem = _item; unsafe { if (XSendMessage.XSend(_hwnd, NativeMethods.LVM_GETITEMINDEXRECT, new IntPtr(&ii), new IntPtr(&itemRectangle), Marshal.SizeOf(ii.GetType()), Marshal.SizeOf(itemRectangle.GetType()))) { if (Misc.MapWindowPoints(_hwnd, IntPtr.Zero, ref itemRectangle, 2)) { boundingRectangle = itemRectangle.ToRect(Misc.IsControlRTL(_hwnd)); return boundingRectangle; } } } } } // If this node represents the container itself... if (WindowsListView.GetItemRect(_hwnd, _item, NativeMethods.LVIR_BOUNDS, out itemRectangle)) { boundingRectangle = itemRectangle.ToRect(Misc.IsControlRTL(_hwnd)); } return boundingRectangle; } } //Gets the controls help text internal override string HelpText { get { // Getting tooltips from Win32 APIs is currently broken. See WinOS Bugs #1454943. //string helpText = WindowsListView.GetItemToolTipText(_hwnd); //if (string.IsNullOrEmpty(helpText)) string helpText = ""; { // IAccessible acc = AccessibleObject; if (acc != null) { // in ListViewItem class _item is idChild - 1 Accessible accItem = Accessible.Wrap(acc, _item + 1); if (accItem != null) { helpText = accItem.HelpText; } } } return string.IsNullOrEmpty(helpText) ? null : helpText; } } //Gets the localized name internal override string LocalizedName { get { string text = GetText(_hwnd, _item, 0); if (string.IsNullOrEmpty(text)) { IAccessible acc = AccessibleObject; if (acc != null) { // in ListViewItem class _item is idChild - 1 Accessible accItem = Accessible.Wrap(acc, _item + 1); if (accItem != null) { text = accItem.Name; } } } return text; } } // Sets the focus to this item. internal override bool SetFocus () { // Set the item's state to focused. return WindowsListView.SetItemFocused (_hwnd, _item); } internal override object GetElementProperty(AutomationProperty propertyId) { if (propertyId == AutomationElement.ClickablePointProperty) { // Special case ClickablePoint - for details view, we need to // return a point on the first item. (The default impl in proxy simple // excludes the children when looking for a point.) NativeMethods.Win32Point clickPoint; if(GetListviewitemClickablePoint (out clickPoint)) { return new double[] { clickPoint.x, clickPoint.y }; } } // EventManager.DispatchEvent() genericaly uses GetElementProperty() // to get properties during a property change event. Proccess ToggleStateProperty // so the ToggleStateProperty Change Event can get the correct state. else if (propertyId == TogglePattern.ToggleStateProperty && IsItemWithCheckbox(_hwnd, _item)) { IToggleProvider listViewItemCheckbox = (IToggleProvider)CreateListViewItemCheckbox(); if (listViewItemCheckbox != null) { return listViewItemCheckbox.ToggleState; } } return base.GetElementProperty(propertyId); } #endregion #region ProxyFragment Interface // 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) { int item = child._item; if (WindowsListView.IsDetailMode (_hwnd)) { item++; int countCol = GetSubItemCount (_hwnd); if (item >= 0 && item < countCol) { return CreateListViewSubItem (item); } } return null; } // 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) { int item = child._item; if (IsItemWithCheckbox(_hwnd, _item) && item == 0) { return CreateListViewItemCheckbox(); } else if (WindowsListView.IsDetailMode (_hwnd)) { int countCol = GetSubItemCount (_hwnd); if (item > 0 && item < countCol) { return CreateListViewSubItem(item - 1); } } return null; } // Returns the first child element in the raw hierarchy. internal override ProxySimple GetFirstChild () { if (IsItemWithCheckbox(_hwnd, _item)) { return CreateListViewItemCheckbox(); } else if (WindowsListView.IsDetailMode(_hwnd)) { int countCol = GetSubItemCount (_hwnd); if (countCol > 0) { return CreateListViewSubItem (0); } } return null; } // Returns the last child element in the raw hierarchy. internal override ProxySimple GetLastChild () { if (WindowsListView.IsDetailMode (_hwnd)) { int countCol = GetSubItemCount (_hwnd); if (countCol > 0) { return CreateListViewSubItem (countCol - 1); } } if (IsItemWithCheckbox(_hwnd, _item)) { return CreateListViewItemCheckbox(); } return null; } // Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint (int x, int y) { // Test for the checkbox first if (IsItemWithCheckbox (_hwnd, _item)) { NativeMethods.Win32Rect checkboxRectangle = ListViewItemCheckbox.ListViewCheckBoxRect (_hwnd, _item); if (!checkboxRectangle.IsEmpty && Misc.PtInRect(ref checkboxRectangle, x, y)) { // listviewitem checkbox return new ListViewItemCheckbox (_hwnd, this, _item, _checkbox); } } if (WindowsListView.IsDetailMode (_hwnd)) { // test for subitem (returns either subitem or lvitem) return ListViewSubItem.ElementProviderFromPoint (_hwnd, this, _item, x, y); } return this; } // Returns an item corresponding to the focused element (if there is one), or null otherwise. internal override ProxySimple GetFocus () { if (_isComctrlV6OnOsVerV6orHigher) { int columns = ListViewItem.GetSubItemCount (_hwnd); if (columns > 0) { int column = (int)Misc.ProxySendMessage(_hwnd, NativeMethods.LVM_GETFOCUSEDCOLUMN, IntPtr.Zero, IntPtr.Zero); if (column >= 0) { return CreateListViewSubItem (column); } } } return this; } #endregion #region SelectionItem Pattern // Selects this element void ISelectionItemProvider.Select () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // simple case: object already selected - only works for single selection element if (!WindowsListView.MultiSelected (_hwnd) && WindowsListView.IsItemSelected (_hwnd, _item)) { return; } // Unselect all items. WindowsListView.UnselectAll (_hwnd); // Select the specified item. if (!WindowsListView.SelectItem(_hwnd, _item)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } // Adds this element to the selection void ISelectionItemProvider.AddToSelection () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // simple case: object already selected if (WindowsListView.IsItemSelected (_hwnd, _item)) { return; } // object does not support multi-selection if (!WindowsListView.MultiSelected(_hwnd)) { IRawElementProviderSimple container = ((ISelectionItemProvider)this).SelectionContainer; bool selectionRequired = container != null ? ((ISelectionProvider)container).IsSelectionRequired : true; // For single selection containers that IsSelectionRequired == false and nothing is selected // an AddToSelection is valid. if (selectionRequired || WindowsListView.GetSelectedItemCount(_hwnd) > 0) { throw new InvalidOperationException(SR.Get(SRID.DoesNotSupportMultipleSelection)); } } // At this point we know: Item either supports multiple selection or nothing // is selected in the list // Try to select an item if (!WindowsListView.SelectItem(_hwnd, _item)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } // Removes this element from the selection void ISelectionItemProvider.RemoveFromSelection () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // simple case: item is not selected if (!WindowsListView.IsItemSelected (_hwnd, _item)) { return; } // object does not support multi-selection if (!WindowsListView.MultiSelected (_hwnd)) { IRawElementProviderSimple container = ((ISelectionItemProvider)this).SelectionContainer; bool selectionRequired = container != null ? ((ISelectionProvider)container).IsSelectionRequired : true; // For single selection containers that IsSelectionRequired == false a // RemoveFromSelection is valid. if (selectionRequired) { throw new InvalidOperationException(SR.Get(SRID.SelectionRequired)); } } // try to unselect the item if (!WindowsListView.UnSelectItem(_hwnd, _item)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } // True if this element is part of the the selection bool ISelectionItemProvider.IsSelected { get { return WindowsListView.IsItemSelected (_hwnd, _item); } } // Returns the container for this element IRawElementProviderSimple ISelectionItemProvider.SelectionContainer { get { // SelectionContainer is always a listview item // However it is possible that between listview item and the listview // we have a Group, if this is the case skip it. ProxyFragment parent = _parent; while (!(parent is WindowsListView)) { System.Diagnostics.Debug.Assert (parent != null, "Hit null while looking for the SelectionContainer"); parent = parent._parent; } return parent; } } #endregion SelectionItem Pattern #region InvokePattern // Same as clicking on a list item. void IInvokeProvider.Invoke () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } if (WindowsListView.Scrollable (_hwnd)) { // ensure item vertical visibility WindowsListView.EnsureVisible (_hwnd, _item, true); } NativeMethods.Win32Point clickPoint; // try to obtaine the clickable point if (!GetListviewitemClickablePoint (out clickPoint)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } Click(clickPoint); } #endregion Invoke Pattern #region Value Pattern void IValueProvider.SetValue (string val) { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } SetValue(val, _hwnd, _item); } // Request to get the value that this UI element is representing as a string string IValueProvider.Value { get { return ListViewItem.GetText (_hwnd, _item, 0); } } // Read only status bool IValueProvider.IsReadOnly { get { return !WindowsListView.ListViewEditable (_hwnd); } } #endregion ValuePattern #region GridItemPattern int IGridItemProvider.Row { get { if (WindowsListView.IsGroupViewEnabled (_hwnd)) { return GetItemRowPositionInGroup (); } // Calculation depends on snakeness of the column if (WindowsListView.IsListMode (_hwnd)) { int itemCount = WindowsListView.GetItemCount (_hwnd); int rowCount = WindowsListView.GetRowCountListMode (_hwnd, itemCount); int column = _item / rowCount; return (_item - (column * rowCount)); } int columnCount = WindowsListView.GetColumnCountOtherModes (_hwnd); return _item / columnCount; } } int IGridItemProvider.Column { get { if (WindowsListView.IsGroupViewEnabled (_hwnd)) { return GetItemColumnPositionInGroup (); } // Calculation depends on snakeness of the column if (WindowsListView.IsListMode (_hwnd)) { int itemCount = WindowsListView.GetItemCount (_hwnd); int rowCount = WindowsListView.GetRowCountListMode (_hwnd, itemCount); return _item / rowCount; } int columnCount = WindowsListView.GetColumnCountOtherModes (_hwnd); int row = _item / columnCount; return (_item - (row * columnCount)); } } int IGridItemProvider.RowSpan { get { return 1; } } int IGridItemProvider.ColumnSpan { get { return 1; } } IRawElementProviderSimple IGridItemProvider.ContainingGrid { get { return _parent; } } #endregion GridItemPattern #region ScrollItem Pattern void IScrollItemProvider.ScrollIntoView() { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // Currently this ignores the alignToTop, as there is no easy way to set something to the bottom of a listbox if (!WindowsListView.Scrollable(_hwnd)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } // ensure item vertical visibility WindowsListView.EnsureVisible(_hwnd, _item, false); } #endregion ScrollItem Pattern //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods internal static int GetSubItemCount (IntPtr hwnd) { // Subitems are only available in details mode. if(WindowsListView.IsDetailMode(hwnd)) { IntPtr hwndHeader = WindowsListView.ListViewGetHeader (hwnd); if (hwndHeader == IntPtr.Zero) { return 0; } return WindowsListView.HeaderItemCount (hwndHeader); } return -1; } // retrieves listview item/subitem text internal static string GetText (IntPtr hwnd, int item, int subitem) { NativeMethods.LVITEM lvitem = new NativeMethods.LVITEM (); lvitem.mask = NativeMethods.LVIF_TEXT; lvitem.iItem = item; lvitem.iSubItem = subitem; return WindowsListView.GetItemText (hwnd, lvitem); } // detect if given listviewitem has a checkbox internal static bool IsItemWithCheckbox (IntPtr hwnd, int item) { if (!WindowsListView.CheckBoxes (hwnd)) { return false; } // this listview supports checkbox, detect if // current item has it return (CheckState.NoCheckbox != (CheckState) WindowsListView.GetCheckedState (hwnd, item)); } // retrieve an id of the group to which this lvitem belongs // valid only if lv has groups enabled static internal int GetGroupID (IntPtr hwnd, int lvItem) { System.Diagnostics.Debug.Assert (WindowsListView.IsGroupViewEnabled (hwnd), "GetGroupID: called when lv does not have groups"); NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6 (); item.mask = NativeMethods.LVIF_GROUPID; item.iItem = lvItem; if (XSendMessage.GetItem(hwnd, ref item)) { return item.iGroupID; } return -1; } internal static void SetValue (string val, IntPtr hwnd, int item) { // PerSharp/PreFast will flag this as warning 6507/56507: Prefer 'string.IsNullOrEmpty(val)' over checks for null and/or emptiness. // An empty strings is valued here, while a null string is not. // Therefore we can not use IsNullOrEmpty() here, suppress the warning. #pragma warning suppress 6507 if (val == null) { throw new ArgumentNullException ("val"); } if (!WindowsListView.ListViewEditable (hwnd)) { throw new InvalidOperationException(SR.Get(SRID.ValueReadonly)); } Misc.SetFocus(hwnd); // set focus to the item WindowsListView.SetItemFocused (hwnd, item); // retrieve edit window IntPtr hwndEdit = WindowsListView.ListViewEditLabel (hwnd, item); if (IntPtr.Zero == hwndEdit) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } // re-use editbox proxy to do the job // Note: we will pass null and -1 for some of the parameters // this is ok, since the only thing that matters to us is an ability to set the text // and these parameters irrelevant for our task WindowsEditBox editBox = new WindowsEditBox (hwndEdit, null, -1); // get value pattern IValueProvider valueProvider = editBox.GetPatternProvider (ValuePattern.Pattern) as IValueProvider; // try to set user-provided text bool setValueSucceeded = false; try { valueProvider.SetValue (val); setValueSucceeded = true; } finally { // even if there is a problem doing SetValue need to exit // editing mode (e.g. cleanup from editing mode). FinishEditing(setValueSucceeded, hwnd, hwndEdit); } // Need to give some time for the control to do all its processing. bool wasTextSet = false; for (int i = 0; i < 10; i++) { System.Threading.Thread.Sleep(1); // Now see if the item really got set. if (val.Equals(ListViewItem.GetText(hwnd, item, 0))) { wasTextSet = true; break; } } if (!wasTextSet) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } #endregion Internal Methods //----------------------------------------------------- // // Internal Fields // //------------------------------------------------------ #region Internal Fields // Represent the state of the checkbox, for lvitem with checkbox internal enum CheckState: int { NoCheckbox = -1, Unchecked = 0, Checked = 1 } #endregion Internal Fields //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods // This routine is only called on elements belonging to an hwnd that has the focus. protected override bool IsFocused () { return WindowsListView.IsItemFocused (_hwnd, _item); } // To test if a list view item is offscreen, we need to // take into account the fact that it may be obscured by // the list view header. internal override bool IsOffscreen() { IntPtr hwndHeader = WindowsListView.ListViewGetHeader(_hwnd); if (hwndHeader != IntPtr.Zero) { NativeMethods.Win32Rect listViewRect = new NativeMethods.Win32Rect(); NativeMethods.Win32Rect headerRect = new NativeMethods.Win32Rect(); if (Misc.GetWindowRect(hwndHeader, ref headerRect) && Misc.GetClientRectInScreenCoordinates(_hwnd, ref listViewRect)) { // Remove the listview header rect. listViewRect.top = headerRect.bottom; NativeMethods.Win32Rect itemRect = new NativeMethods.Win32Rect(BoundingRectangle); if (!listViewRect.IsEmpty && !Misc.IsItemVisible(ref listViewRect, ref itemRect)) { return true; } } } return false; } #endregion //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods private ProxySimple CreateListViewSubItem (int index) { return new ListViewSubItem (_hwnd, this, index, _item); } private ProxySimple CreateListViewItemCheckbox () { return new ListViewItemCheckbox (_hwnd, this, _item, _checkbox); } // detect if this listviewitem needs to support GridItem pattern static private bool IsImplementingGrid (IntPtr hwnd) { // in the detail mode, GridItem will be implemented on the subitem // and not item if (WindowsListView.IsDetailMode (hwnd)) { return false; } return (WindowsListView.IsListMode (hwnd) || WindowsListView.ListViewAutoArrange (hwnd)); } // 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; } private void Click (NativeMethods.Win32Point clickPoint) { Misc.MouseClick(clickPoint.x, clickPoint.y, !WindowsListView.ListViewSingleClickActivate(_hwnd)); } // send an enter key to the control // hence finishing label editting // Assumption: control has focus private static void FinishEditing (bool setValueSucceeded, IntPtr hwnd, IntPtr hwndEdit) { // If editing was successful exit editing mode using Return key otherwise Esc out IntPtr key = (IntPtr)((setValueSucceeded) ? NativeMethods.VK_RETURN : NativeMethods.VK_ESCAPE); // get the scankey int scanCode = SafeNativeMethods.MapVirtualKey (NativeMethods.VK_RETURN, 0); scanCode <<= 16; IntPtr keyUpLParam = new IntPtr (scanCode + (1 << 31) + (1 << 30)); // send keyboard message Misc.ProxySendMessage(hwndEdit, NativeMethods.WM_KEYDOWN, key, new IntPtr(scanCode)); Misc.ProxySendMessage(hwnd, NativeMethods.WM_KEYUP, key, keyUpLParam); } // 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; } // retrieve lvitem row position in the Grid // To be called only when Group is enabled private int GetItemRowPositionInGroup () { // 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); if (position != -1) { // number of columns in the grid int columnCount = WindowsListViewGroup.GetColumnCountExternal (_hwnd, groupID); // calculate the row position of the item return position / columnCount; } } } return -1; } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ #region Private Fields private const int _checkbox = -1; bool _isComctrlV6OnOsVerV6orHigher; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Win32 ListView Item proxy // // History: // Jean-Francois Peyroux, alexsn - Created (in DotNet) // 2003/08/11 - alexsn Updated for WCP // //--------------------------------------------------------------------------- // PRESHARP: In order to avoid generating warnings about unknown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 using System; using System.ComponentModel; using System.Windows.Automation; using System.Windows.Automation.Provider; using System.Runtime.InteropServices; using System.Windows; using Accessibility; using MS.Win32; namespace MS.Internal.AutomationProxies { internal class ListViewItem : ProxyFragment, IInvokeProvider, ISelectionItemProvider, IValueProvider, IGridItemProvider, IScrollItemProvider { // ----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors internal ListViewItem (IntPtr hwnd, ProxyFragment parent, int item) : base (hwnd, parent, item) { // Set the strings to return properly the properties. if (WindowsListView.IsDetailMode(hwnd)) { _cControlType = ControlType.DataItem; } else { _cControlType = ControlType.ListItem; } _fHasPersistentID = false; _fIsKeyboardFocusable = true; _isComctrlV6OnOsVerV6orHigher = Misc.IsComctrlV6OnOsVerV6orHigher(hwnd); } #endregion Constructos //------------------------------------------------------ // // Patterns Implementation // //----------------------------------------------------- #region ProxySimple Interface // Returns a pattern interface if supported. internal override object GetPatternProvider (AutomationPattern iid) { if (iid == InvokePattern.Pattern && WindowsListView.ListViewInvokable(_hwnd)) { return this; } if (iid == SelectionItemPattern.Pattern) { return this; } if (iid == ValuePattern.Pattern && WindowsListView.ListViewEditable (_hwnd)) { return this; } if (iid == GridItemPattern.Pattern && IsImplementingGrid (_hwnd)) { return this; } if (iid == TogglePattern.Pattern && IsItemWithCheckbox(_hwnd, _item)) { return CreateListViewItemCheckbox(); } if (iid == ScrollItemPattern.Pattern && WindowScroll.IsScrollable(_hwnd)) { return this; } return null; } // Gets the bounding rectangle for this element internal override Rect BoundingRectangle { get { NativeMethods.Win32Rect itemRectangle = NativeMethods.Win32Rect.Empty; Rect boundingRectangle = Rect.Empty; // If we have a listview that could support group view we need to use a diferent method // to get the builnding rect. If anything fails trying this way just fall back to the old way // of doing things. if (_isComctrlV6OnOsVerV6orHigher) { itemRectangle.left = NativeMethods.LVIR_BOUNDS; WindowsListViewGroup windowsListViewGroup = _parent as WindowsListViewGroup; if (windowsListViewGroup != null) { // The group might have been destroyed by an event WindowsListView._groupsCollection.EnsureCreation (_hwnd); GroupManager manager = WindowsListView._groupsCollection[_hwnd]; int [] groupIds = manager.GetGroupIds (); // find the index for this group int index; for (index = 0; index < groupIds.Length && windowsListViewGroup.ID != groupIds[index]; index++); if (index >= groupIds.Length) { return boundingRectangle; } NativeMethods.LVITEMINDEX ii = new NativeMethods.LVITEMINDEX(); ii.iGroup = index; ii.iItem = _item; unsafe { if (XSendMessage.XSend(_hwnd, NativeMethods.LVM_GETITEMINDEXRECT, new IntPtr(&ii), new IntPtr(&itemRectangle), Marshal.SizeOf(ii.GetType()), Marshal.SizeOf(itemRectangle.GetType()))) { if (Misc.MapWindowPoints(_hwnd, IntPtr.Zero, ref itemRectangle, 2)) { boundingRectangle = itemRectangle.ToRect(Misc.IsControlRTL(_hwnd)); return boundingRectangle; } } } } } // If this node represents the container itself... if (WindowsListView.GetItemRect(_hwnd, _item, NativeMethods.LVIR_BOUNDS, out itemRectangle)) { boundingRectangle = itemRectangle.ToRect(Misc.IsControlRTL(_hwnd)); } return boundingRectangle; } } //Gets the controls help text internal override string HelpText { get { // Getting tooltips from Win32 APIs is currently broken. See WinOS Bugs #1454943. //string helpText = WindowsListView.GetItemToolTipText(_hwnd); //if (string.IsNullOrEmpty(helpText)) string helpText = ""; { // IAccessible acc = AccessibleObject; if (acc != null) { // in ListViewItem class _item is idChild - 1 Accessible accItem = Accessible.Wrap(acc, _item + 1); if (accItem != null) { helpText = accItem.HelpText; } } } return string.IsNullOrEmpty(helpText) ? null : helpText; } } //Gets the localized name internal override string LocalizedName { get { string text = GetText(_hwnd, _item, 0); if (string.IsNullOrEmpty(text)) { IAccessible acc = AccessibleObject; if (acc != null) { // in ListViewItem class _item is idChild - 1 Accessible accItem = Accessible.Wrap(acc, _item + 1); if (accItem != null) { text = accItem.Name; } } } return text; } } // Sets the focus to this item. internal override bool SetFocus () { // Set the item's state to focused. return WindowsListView.SetItemFocused (_hwnd, _item); } internal override object GetElementProperty(AutomationProperty propertyId) { if (propertyId == AutomationElement.ClickablePointProperty) { // Special case ClickablePoint - for details view, we need to // return a point on the first item. (The default impl in proxy simple // excludes the children when looking for a point.) NativeMethods.Win32Point clickPoint; if(GetListviewitemClickablePoint (out clickPoint)) { return new double[] { clickPoint.x, clickPoint.y }; } } // EventManager.DispatchEvent() genericaly uses GetElementProperty() // to get properties during a property change event. Proccess ToggleStateProperty // so the ToggleStateProperty Change Event can get the correct state. else if (propertyId == TogglePattern.ToggleStateProperty && IsItemWithCheckbox(_hwnd, _item)) { IToggleProvider listViewItemCheckbox = (IToggleProvider)CreateListViewItemCheckbox(); if (listViewItemCheckbox != null) { return listViewItemCheckbox.ToggleState; } } return base.GetElementProperty(propertyId); } #endregion #region ProxyFragment Interface // 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) { int item = child._item; if (WindowsListView.IsDetailMode (_hwnd)) { item++; int countCol = GetSubItemCount (_hwnd); if (item >= 0 && item < countCol) { return CreateListViewSubItem (item); } } return null; } // 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) { int item = child._item; if (IsItemWithCheckbox(_hwnd, _item) && item == 0) { return CreateListViewItemCheckbox(); } else if (WindowsListView.IsDetailMode (_hwnd)) { int countCol = GetSubItemCount (_hwnd); if (item > 0 && item < countCol) { return CreateListViewSubItem(item - 1); } } return null; } // Returns the first child element in the raw hierarchy. internal override ProxySimple GetFirstChild () { if (IsItemWithCheckbox(_hwnd, _item)) { return CreateListViewItemCheckbox(); } else if (WindowsListView.IsDetailMode(_hwnd)) { int countCol = GetSubItemCount (_hwnd); if (countCol > 0) { return CreateListViewSubItem (0); } } return null; } // Returns the last child element in the raw hierarchy. internal override ProxySimple GetLastChild () { if (WindowsListView.IsDetailMode (_hwnd)) { int countCol = GetSubItemCount (_hwnd); if (countCol > 0) { return CreateListViewSubItem (countCol - 1); } } if (IsItemWithCheckbox(_hwnd, _item)) { return CreateListViewItemCheckbox(); } return null; } // Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint (int x, int y) { // Test for the checkbox first if (IsItemWithCheckbox (_hwnd, _item)) { NativeMethods.Win32Rect checkboxRectangle = ListViewItemCheckbox.ListViewCheckBoxRect (_hwnd, _item); if (!checkboxRectangle.IsEmpty && Misc.PtInRect(ref checkboxRectangle, x, y)) { // listviewitem checkbox return new ListViewItemCheckbox (_hwnd, this, _item, _checkbox); } } if (WindowsListView.IsDetailMode (_hwnd)) { // test for subitem (returns either subitem or lvitem) return ListViewSubItem.ElementProviderFromPoint (_hwnd, this, _item, x, y); } return this; } // Returns an item corresponding to the focused element (if there is one), or null otherwise. internal override ProxySimple GetFocus () { if (_isComctrlV6OnOsVerV6orHigher) { int columns = ListViewItem.GetSubItemCount (_hwnd); if (columns > 0) { int column = (int)Misc.ProxySendMessage(_hwnd, NativeMethods.LVM_GETFOCUSEDCOLUMN, IntPtr.Zero, IntPtr.Zero); if (column >= 0) { return CreateListViewSubItem (column); } } } return this; } #endregion #region SelectionItem Pattern // Selects this element void ISelectionItemProvider.Select () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // simple case: object already selected - only works for single selection element if (!WindowsListView.MultiSelected (_hwnd) && WindowsListView.IsItemSelected (_hwnd, _item)) { return; } // Unselect all items. WindowsListView.UnselectAll (_hwnd); // Select the specified item. if (!WindowsListView.SelectItem(_hwnd, _item)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } // Adds this element to the selection void ISelectionItemProvider.AddToSelection () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // simple case: object already selected if (WindowsListView.IsItemSelected (_hwnd, _item)) { return; } // object does not support multi-selection if (!WindowsListView.MultiSelected(_hwnd)) { IRawElementProviderSimple container = ((ISelectionItemProvider)this).SelectionContainer; bool selectionRequired = container != null ? ((ISelectionProvider)container).IsSelectionRequired : true; // For single selection containers that IsSelectionRequired == false and nothing is selected // an AddToSelection is valid. if (selectionRequired || WindowsListView.GetSelectedItemCount(_hwnd) > 0) { throw new InvalidOperationException(SR.Get(SRID.DoesNotSupportMultipleSelection)); } } // At this point we know: Item either supports multiple selection or nothing // is selected in the list // Try to select an item if (!WindowsListView.SelectItem(_hwnd, _item)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } // Removes this element from the selection void ISelectionItemProvider.RemoveFromSelection () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // simple case: item is not selected if (!WindowsListView.IsItemSelected (_hwnd, _item)) { return; } // object does not support multi-selection if (!WindowsListView.MultiSelected (_hwnd)) { IRawElementProviderSimple container = ((ISelectionItemProvider)this).SelectionContainer; bool selectionRequired = container != null ? ((ISelectionProvider)container).IsSelectionRequired : true; // For single selection containers that IsSelectionRequired == false a // RemoveFromSelection is valid. if (selectionRequired) { throw new InvalidOperationException(SR.Get(SRID.SelectionRequired)); } } // try to unselect the item if (!WindowsListView.UnSelectItem(_hwnd, _item)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } // True if this element is part of the the selection bool ISelectionItemProvider.IsSelected { get { return WindowsListView.IsItemSelected (_hwnd, _item); } } // Returns the container for this element IRawElementProviderSimple ISelectionItemProvider.SelectionContainer { get { // SelectionContainer is always a listview item // However it is possible that between listview item and the listview // we have a Group, if this is the case skip it. ProxyFragment parent = _parent; while (!(parent is WindowsListView)) { System.Diagnostics.Debug.Assert (parent != null, "Hit null while looking for the SelectionContainer"); parent = parent._parent; } return parent; } } #endregion SelectionItem Pattern #region InvokePattern // Same as clicking on a list item. void IInvokeProvider.Invoke () { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } if (WindowsListView.Scrollable (_hwnd)) { // ensure item vertical visibility WindowsListView.EnsureVisible (_hwnd, _item, true); } NativeMethods.Win32Point clickPoint; // try to obtaine the clickable point if (!GetListviewitemClickablePoint (out clickPoint)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } Click(clickPoint); } #endregion Invoke Pattern #region Value Pattern void IValueProvider.SetValue (string val) { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } SetValue(val, _hwnd, _item); } // Request to get the value that this UI element is representing as a string string IValueProvider.Value { get { return ListViewItem.GetText (_hwnd, _item, 0); } } // Read only status bool IValueProvider.IsReadOnly { get { return !WindowsListView.ListViewEditable (_hwnd); } } #endregion ValuePattern #region GridItemPattern int IGridItemProvider.Row { get { if (WindowsListView.IsGroupViewEnabled (_hwnd)) { return GetItemRowPositionInGroup (); } // Calculation depends on snakeness of the column if (WindowsListView.IsListMode (_hwnd)) { int itemCount = WindowsListView.GetItemCount (_hwnd); int rowCount = WindowsListView.GetRowCountListMode (_hwnd, itemCount); int column = _item / rowCount; return (_item - (column * rowCount)); } int columnCount = WindowsListView.GetColumnCountOtherModes (_hwnd); return _item / columnCount; } } int IGridItemProvider.Column { get { if (WindowsListView.IsGroupViewEnabled (_hwnd)) { return GetItemColumnPositionInGroup (); } // Calculation depends on snakeness of the column if (WindowsListView.IsListMode (_hwnd)) { int itemCount = WindowsListView.GetItemCount (_hwnd); int rowCount = WindowsListView.GetRowCountListMode (_hwnd, itemCount); return _item / rowCount; } int columnCount = WindowsListView.GetColumnCountOtherModes (_hwnd); int row = _item / columnCount; return (_item - (row * columnCount)); } } int IGridItemProvider.RowSpan { get { return 1; } } int IGridItemProvider.ColumnSpan { get { return 1; } } IRawElementProviderSimple IGridItemProvider.ContainingGrid { get { return _parent; } } #endregion GridItemPattern #region ScrollItem Pattern void IScrollItemProvider.ScrollIntoView() { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } // Currently this ignores the alignToTop, as there is no easy way to set something to the bottom of a listbox if (!WindowsListView.Scrollable(_hwnd)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } // ensure item vertical visibility WindowsListView.EnsureVisible(_hwnd, _item, false); } #endregion ScrollItem Pattern //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods internal static int GetSubItemCount (IntPtr hwnd) { // Subitems are only available in details mode. if(WindowsListView.IsDetailMode(hwnd)) { IntPtr hwndHeader = WindowsListView.ListViewGetHeader (hwnd); if (hwndHeader == IntPtr.Zero) { return 0; } return WindowsListView.HeaderItemCount (hwndHeader); } return -1; } // retrieves listview item/subitem text internal static string GetText (IntPtr hwnd, int item, int subitem) { NativeMethods.LVITEM lvitem = new NativeMethods.LVITEM (); lvitem.mask = NativeMethods.LVIF_TEXT; lvitem.iItem = item; lvitem.iSubItem = subitem; return WindowsListView.GetItemText (hwnd, lvitem); } // detect if given listviewitem has a checkbox internal static bool IsItemWithCheckbox (IntPtr hwnd, int item) { if (!WindowsListView.CheckBoxes (hwnd)) { return false; } // this listview supports checkbox, detect if // current item has it return (CheckState.NoCheckbox != (CheckState) WindowsListView.GetCheckedState (hwnd, item)); } // retrieve an id of the group to which this lvitem belongs // valid only if lv has groups enabled static internal int GetGroupID (IntPtr hwnd, int lvItem) { System.Diagnostics.Debug.Assert (WindowsListView.IsGroupViewEnabled (hwnd), "GetGroupID: called when lv does not have groups"); NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6 (); item.mask = NativeMethods.LVIF_GROUPID; item.iItem = lvItem; if (XSendMessage.GetItem(hwnd, ref item)) { return item.iGroupID; } return -1; } internal static void SetValue (string val, IntPtr hwnd, int item) { // PerSharp/PreFast will flag this as warning 6507/56507: Prefer 'string.IsNullOrEmpty(val)' over checks for null and/or emptiness. // An empty strings is valued here, while a null string is not. // Therefore we can not use IsNullOrEmpty() here, suppress the warning. #pragma warning suppress 6507 if (val == null) { throw new ArgumentNullException ("val"); } if (!WindowsListView.ListViewEditable (hwnd)) { throw new InvalidOperationException(SR.Get(SRID.ValueReadonly)); } Misc.SetFocus(hwnd); // set focus to the item WindowsListView.SetItemFocused (hwnd, item); // retrieve edit window IntPtr hwndEdit = WindowsListView.ListViewEditLabel (hwnd, item); if (IntPtr.Zero == hwndEdit) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } // re-use editbox proxy to do the job // Note: we will pass null and -1 for some of the parameters // this is ok, since the only thing that matters to us is an ability to set the text // and these parameters irrelevant for our task WindowsEditBox editBox = new WindowsEditBox (hwndEdit, null, -1); // get value pattern IValueProvider valueProvider = editBox.GetPatternProvider (ValuePattern.Pattern) as IValueProvider; // try to set user-provided text bool setValueSucceeded = false; try { valueProvider.SetValue (val); setValueSucceeded = true; } finally { // even if there is a problem doing SetValue need to exit // editing mode (e.g. cleanup from editing mode). FinishEditing(setValueSucceeded, hwnd, hwndEdit); } // Need to give some time for the control to do all its processing. bool wasTextSet = false; for (int i = 0; i < 10; i++) { System.Threading.Thread.Sleep(1); // Now see if the item really got set. if (val.Equals(ListViewItem.GetText(hwnd, item, 0))) { wasTextSet = true; break; } } if (!wasTextSet) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } } #endregion Internal Methods //----------------------------------------------------- // // Internal Fields // //------------------------------------------------------ #region Internal Fields // Represent the state of the checkbox, for lvitem with checkbox internal enum CheckState: int { NoCheckbox = -1, Unchecked = 0, Checked = 1 } #endregion Internal Fields //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods // This routine is only called on elements belonging to an hwnd that has the focus. protected override bool IsFocused () { return WindowsListView.IsItemFocused (_hwnd, _item); } // To test if a list view item is offscreen, we need to // take into account the fact that it may be obscured by // the list view header. internal override bool IsOffscreen() { IntPtr hwndHeader = WindowsListView.ListViewGetHeader(_hwnd); if (hwndHeader != IntPtr.Zero) { NativeMethods.Win32Rect listViewRect = new NativeMethods.Win32Rect(); NativeMethods.Win32Rect headerRect = new NativeMethods.Win32Rect(); if (Misc.GetWindowRect(hwndHeader, ref headerRect) && Misc.GetClientRectInScreenCoordinates(_hwnd, ref listViewRect)) { // Remove the listview header rect. listViewRect.top = headerRect.bottom; NativeMethods.Win32Rect itemRect = new NativeMethods.Win32Rect(BoundingRectangle); if (!listViewRect.IsEmpty && !Misc.IsItemVisible(ref listViewRect, ref itemRect)) { return true; } } } return false; } #endregion //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods private ProxySimple CreateListViewSubItem (int index) { return new ListViewSubItem (_hwnd, this, index, _item); } private ProxySimple CreateListViewItemCheckbox () { return new ListViewItemCheckbox (_hwnd, this, _item, _checkbox); } // detect if this listviewitem needs to support GridItem pattern static private bool IsImplementingGrid (IntPtr hwnd) { // in the detail mode, GridItem will be implemented on the subitem // and not item if (WindowsListView.IsDetailMode (hwnd)) { return false; } return (WindowsListView.IsListMode (hwnd) || WindowsListView.ListViewAutoArrange (hwnd)); } // 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; } private void Click (NativeMethods.Win32Point clickPoint) { Misc.MouseClick(clickPoint.x, clickPoint.y, !WindowsListView.ListViewSingleClickActivate(_hwnd)); } // send an enter key to the control // hence finishing label editting // Assumption: control has focus private static void FinishEditing (bool setValueSucceeded, IntPtr hwnd, IntPtr hwndEdit) { // If editing was successful exit editing mode using Return key otherwise Esc out IntPtr key = (IntPtr)((setValueSucceeded) ? NativeMethods.VK_RETURN : NativeMethods.VK_ESCAPE); // get the scankey int scanCode = SafeNativeMethods.MapVirtualKey (NativeMethods.VK_RETURN, 0); scanCode <<= 16; IntPtr keyUpLParam = new IntPtr (scanCode + (1 << 31) + (1 << 30)); // send keyboard message Misc.ProxySendMessage(hwndEdit, NativeMethods.WM_KEYDOWN, key, new IntPtr(scanCode)); Misc.ProxySendMessage(hwnd, NativeMethods.WM_KEYUP, key, keyUpLParam); } // 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; } // retrieve lvitem row position in the Grid // To be called only when Group is enabled private int GetItemRowPositionInGroup () { // 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); if (position != -1) { // number of columns in the grid int columnCount = WindowsListViewGroup.GetColumnCountExternal (_hwnd, groupID); // calculate the row position of the item return position / columnCount; } } } return -1; } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ #region Private Fields private const int _checkbox = -1; bool _isComctrlV6OnOsVerV6orHigher; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TimeSpanStorage.cs
- InheritedPropertyDescriptor.cs
- ClientRolePrincipal.cs
- DependsOnAttribute.cs
- DbModificationCommandTree.cs
- HebrewCalendar.cs
- ChangesetResponse.cs
- SiteMapPath.cs
- CachedPathData.cs
- ButtonBaseAdapter.cs
- ArgumentException.cs
- LinearQuaternionKeyFrame.cs
- XsltArgumentList.cs
- OrderedDictionaryStateHelper.cs
- EtwTrackingBehaviorElement.cs
- DeviceFiltersSection.cs
- TracedNativeMethods.cs
- Models.cs
- VectorConverter.cs
- TypeLibConverter.cs
- TypeUsageBuilder.cs
- RectangleConverter.cs
- ImageUrlEditor.cs
- FileAuthorizationModule.cs
- XmlSchemaImport.cs
- ErrorHandler.cs
- SubstitutionResponseElement.cs
- ContainerSelectorActiveEvent.cs
- HScrollProperties.cs
- SchemaMapping.cs
- AuthorizationContext.cs
- StrokeCollection2.cs
- SeverityFilter.cs
- GridLength.cs
- SignatureDescription.cs
- DataStorage.cs
- TextChangedEventArgs.cs
- InputScopeAttribute.cs
- odbcmetadatafactory.cs
- OdbcParameter.cs
- LocalizedNameDescriptionPair.cs
- DataGridLinkButton.cs
- TagMapCollection.cs
- ComponentEditorPage.cs
- AddInAdapter.cs
- CheckedPointers.cs
- __Filters.cs
- MailMessageEventArgs.cs
- GifBitmapDecoder.cs
- XpsManager.cs
- RNGCryptoServiceProvider.cs
- ResourcePermissionBase.cs
- FormsAuthenticationModule.cs
- XmlCharType.cs
- PropagatorResult.cs
- hresults.cs
- FixedSOMLineRanges.cs
- EntityContainer.cs
- HttpMethodConstraint.cs
- DynamicILGenerator.cs
- ProfilePropertyNameValidator.cs
- FontCacheUtil.cs
- ProtocolsConfiguration.cs
- ViewBox.cs
- RegexCompilationInfo.cs
- AdapterUtil.cs
- TimeSpanValidator.cs
- ApplicationProxyInternal.cs
- PackagePartCollection.cs
- ResourcePermissionBaseEntry.cs
- AutomationProperty.cs
- ShimAsPublicXamlType.cs
- ProfilePropertySettings.cs
- TraceData.cs
- ExecutedRoutedEventArgs.cs
- ServiceAppDomainAssociationProvider.cs
- LazyTextWriterCreator.cs
- ClonableStack.cs
- PartitionResolver.cs
- DataStreams.cs
- PropertyIDSet.cs
- ExpressionConverter.cs
- BuildProviderUtils.cs
- CompilerHelpers.cs
- PeerSecurityHelpers.cs
- ImageListStreamer.cs
- Expr.cs
- WindowsGraphicsWrapper.cs
- TextRangeAdaptor.cs
- remotingproxy.cs
- TrimSurroundingWhitespaceAttribute.cs
- KeyToListMap.cs
- XamlWrappingReader.cs
- DataPagerCommandEventArgs.cs
- EntityProxyFactory.cs
- ColorMap.cs
- ResolvedKeyFrameEntry.cs
- ThreadStateException.cs
- PersonalizableAttribute.cs
- ParentUndoUnit.cs