|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Description: Win32 ListView Item proxy
//
// 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))
{
// Don't need to normalize, GetItemRect returns absolute coordinates.
boundingRectangle = itemRectangle.ToRect(false);
return boundingRectangle;
}
}
}
}
}
// If this node represents the container itself...
if (WindowsListView.GetItemRect(_hwnd, _item, NativeMethods.LVIR_BOUNDS, out itemRectangle))
{
// Don't need to normalize, GetItemRect returns absolute coordinates.
boundingRectangle = itemRectangle.ToRect(false);
}
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 = "";
{
// port the msaa impl for this from .\oleacc\listview.cpp
// failed to get HelpText from tooltips so try MSAA accHelp
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.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.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.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.SelectionRequired);
}
}
// try to unselect the item
if (!WindowsListView.UnSelectItem(_hwnd, _item))
{
throw new InvalidOperationException(SR.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.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.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
ArgumentNullException.ThrowIfNull(val);
if (!WindowsListView.ListViewEditable (hwnd))
{
throw new InvalidOperationException(SR.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.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.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
// Need to implement Bidi?
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
}
}
|