Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / UIAutomation / UIAutomationClient / System / Windows / Automation / Text / TextRange.cs / 1 / TextRange.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: Client-side wrapper for text range.
//
// History:
// 08/01/2003 : Micw Ported to WCP
// 02/09/2004 : a-davidj rewrote for Text Pattern redesign
// and moved to .Text subnamespace.
//
//---------------------------------------------------------------------------
// PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas.
#pragma warning disable 1634, 1691
using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Windows.Automation.Provider;
using MS.Internal.Automation;
namespace System.Windows.Automation.Text
{
// Internal Class that wraps the IntPtr to the TextRange
internal sealed class SafeTextRangeHandle : SafeHandle
{
// Called by P/Invoke when returning SafeHandles
// (Also used by UiaCoreApi to create invalid handles.)
internal SafeTextRangeHandle()
: base(IntPtr.Zero, true)
{
}
// No need to provide a finalizer - SafeHandle's critical finalizer will
// call ReleaseHandle for you.
public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}
override protected bool ReleaseHandle()
{
return UiaCoreApi.UiaTextRangeRelease(handle);
}
}
///
/// Represents a span of text in a Text Pattern container.
///
#if (INTERNAL_COMPILE)
internal class TextPatternRange
#else
public class TextPatternRange
#endif
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
internal TextPatternRange(SafeTextRangeHandle hTextRange, TextPattern pattern)
{
Debug.Assert(!hTextRange.IsInvalid);
Debug.Assert(pattern != null);
_hTextRange = hTextRange;
_pattern = pattern;
}
internal static TextPatternRange Wrap(SafeTextRangeHandle hTextRange, TextPattern pattern)
{
if (hTextRange.IsInvalid)
{
return null;
}
return new TextPatternRange(hTextRange, pattern);
}
internal static TextPatternRange [] Wrap(SafeTextRangeHandle [] hTextRanges, TextPattern pattern)
{
if (hTextRanges == null)
return null;
TextPatternRange[] ranges = new TextPatternRange[hTextRanges.Length];
for (int i = 0; i < hTextRanges.Length; i++)
{
// if invalid, leave as null
if (!hTextRanges[i].IsInvalid)
{
ranges[i] = new TextPatternRange(hTextRanges[i], pattern);
}
}
return ranges;
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
///
/// Retrieves a new range covering an identical span of text. The new range can be manipulated independently from the original.
///
/// The new range.
public TextPatternRange Clone()
{
SafeTextRangeHandle hResultTextRange = UiaCoreApi.TextRange_Clone(_hTextRange);
return Wrap(hResultTextRange, _pattern);
}
///
/// Compares this range with another range.
///
/// A range to compare.
/// The range must have come from the same text provider or an InvalidArgumentException will be thrown.
/// true if both ranges span the same text.
public bool Compare(TextPatternRange range)
{
ValidateRangeArgument(range, "range");
return UiaCoreApi.TextRange_Compare(_hTextRange, range._hTextRange);
}
///
/// Compares the endpoint of this range with the endpoint of another range.
///
/// The endpoint of this range to compare.
/// The range with the other endpoint to compare.
/// The range must have come from the same text provider or an InvalidArgumentException will be thrown.
/// The endpoint on the other range to compare.
/// Returns <0 if this endpoint occurs earlier in the text than the target endpoint.
/// Returns 0 if this endpoint is at the same location as the target endpoint.
/// Returns >0 if this endpoint occurs later in the text than the target endpoint.
public int CompareEndpoints(TextPatternRangeEndpoint endpoint, TextPatternRange targetRange, TextPatternRangeEndpoint targetEndpoint)
{
ValidateEndpointArgument(endpoint, "endpoint");
ValidateRangeArgument(targetRange, "targetRange");
ValidateEndpointArgument(targetEndpoint, "targetEndpoint");
return UiaCoreApi.TextRange_CompareEndpoints(_hTextRange, endpoint, targetRange._hTextRange, targetEndpoint);
}
///
/// Expands the range to an integral number of enclosing units. This could be used, for example,
/// to guarantee that a range endpoint is not in the middle of a word. If the range is already an
/// integral number of the specified units then it remains unchanged.
/// For the TextUnit.Word unit with a degenerate range if the range is immediately before a word,
/// inside that word, or within the whitespace following that word (but not immediately before the next
/// word) then it will expand to include that word.
/// For the TextUnit.Format unit if the range has mixed formatting then the range starting point will
/// be moved backwards over any text that is identically formatted to that at the start of the range
/// and the endpoint will be move forwards over any text that is identically formatted to that at the
/// end of the range.
///
/// The textual unit.
public void ExpandToEnclosingUnit(TextUnit unit)
{
ValidateUnitArgument(unit, "unit");
UiaCoreApi.TextRange_ExpandToEnclosingUnit(_hTextRange, unit);
}
///
/// Searches for a subrange of text that has the specified attribute.
/// To search the entire document use the text pattern's document range.
///
/// The attribute to search for.
/// The value of the specified attribute to search for. The value must be of the exact type specified for the
/// attribute. For example when searching for font size you must specify the size in points as a double.
/// If you specify the point size as an integer then you will never get any matches due to the differing types.
/// true if the last occurring range should be returned instead of the first.
/// A subrange with the specified attribute, or null if no such subrange exists.
public TextPatternRange FindAttribute(AutomationTextAttribute attribute, object value, bool backward)
{
Misc.ValidateArgumentNonNull(attribute, "attribute");
Misc.ValidateArgumentNonNull(value, "value"); // no text attributes can have null as a valid value
// Check that attribute value is of expected type...
AutomationAttributeInfo ai;
if(!Schema.GetAttributeInfo(attribute, out ai))
{
throw new ArgumentException(SR.Get(SRID.UnsupportedAttribute));
}
if (value.GetType() != ai.Type)
{
throw new ArgumentException(SR.Get(SRID.TextAttributeValueWrongType, attribute, ai.Type.Name, value.GetType().Name), "value");
}
// note: if we implement attributes whose values are logical elements, patterns,
// or ranges then we'll need to unwrap the objects here before passing them on to
// the provider.
if (attribute == TextPattern.CultureAttribute)
{
if (value is CultureInfo)
{
value = ((CultureInfo)value).LCID;
}
}
SafeTextRangeHandle hResultTextRange = UiaCoreApi.TextRange_FindAttribute(_hTextRange, attribute.Id, value, backward);
return Wrap(hResultTextRange, _pattern);
}
///
/// Searches for an occurrence of text within the range.
///
/// The text to search for.
/// true if the last occurring range should be returned instead of the first.
/// true if case should be ignored for the purposes of comparison.
/// A subrange with the specified text, or null if no such subrange exists.
public TextPatternRange FindText(string text, bool backward, bool ignoreCase)
{
// PerSharp/PreFast will flag this as warning 6507/56507: Prefer 'string.IsNullOrEmpty(text)' over checks for null and/or emptiness.
// A null string is not should throw an ArgumentNullException while an empty string should throw an ArgumentException.
// Therefore we can not use IsNullOrEmpty() here, suppress the warning.
Misc.ValidateArgumentNonNull(text, "text");
#pragma warning suppress 6507
Misc.ValidateArgument(text.Length != 0, SRID.TextMustNotBeNullOrEmpty);
SafeTextRangeHandle hResultTextRange = UiaCoreApi.TextRange_FindText(_hTextRange, text, backward, ignoreCase);
return Wrap(hResultTextRange, _pattern);
}
///
/// Retrieves the value of a text attribute over the entire range.
///
/// The text attribute.
/// The value of the attribute across the range.
/// If the attribute's value varies over the range then the value is TextPattern.MixedAttributeValue
public object GetAttributeValue(AutomationTextAttribute attribute)
{
Misc.ValidateArgumentNonNull(attribute, "attribute");
AutomationAttributeInfo ai;
if(!Schema.GetAttributeInfo(attribute, out ai))
{
throw new ArgumentException(SR.Get(SRID.UnsupportedAttribute));
}
object obj = UiaCoreApi.TextRange_GetAttributeValue(_hTextRange, attribute.Id);
if (ai.Type.IsEnum && obj is int)
{
// Convert ints from COM Interop to the appropriate enum type
obj = Enum.ToObject(ai.Type, (int)obj);
}
else if (obj != AutomationElement.NotSupported && ai.ObjectConverter != null)
{
// Use a custom converter, if needed (eg. converts LCIDs to CultureInfo)
obj = ai.ObjectConverter(obj);
}
return obj;
}
///
/// Retrieves the bounding rectangles for viewable lines of the range.
///
/// An array of bounding rectangles for each line or portion of a line within the client area of the text provider.
/// No bounding rectangles will be returned for lines that are empty or scrolled out of view. Note that even though a
/// bounding rectangle is returned the corresponding text may not be visible due to overlapping windows.
/// This will not return null, but may return an empty array.
public Rect[] GetBoundingRectangles()
{
return UiaCoreApi.TextRange_GetBoundingRectangles(_hTextRange);
}
///
/// Retrieves the innermost element that encloses this range.
///
/// An element. Usually this element will be the one that supplied this range.
/// However, if the text provider supports child elements such as tables or hyperlinks, then the
/// enclosing element could be a descendant element of the text provider.
///
public AutomationElement GetEnclosingElement()
{
return AutomationElement.Wrap(UiaCoreApi.TextRange_GetEnclosingElement(_hTextRange));
}
///
/// Retrieves the text of the range.
///
/// Specifies the maximum length of the string to return or -1 if no limit is requested.
/// The text of the range possibly truncated to the specified limit.
public string GetText(int maxLength)
{
Misc.ValidateArgumentInRange(maxLength >= -1, "maxLength");
return UiaCoreApi.TextRange_GetText(_hTextRange, maxLength);
}
///
/// Moves the range the specified number of units in the text. Note that the text is not altered. Instead the
/// range spans a different part of the text.
/// If the range is degenerate, this method tries to move the insertion point count units. If the range is nondegenerate
/// and count is greater than zero, this method collapses the range at its end point, moves the resulting range forward
/// to a unit boundary (if it is not already at one), and then tries to move count - 1 units forward. If the range is
/// nondegenerate and count is less than zero, this method collapses the range at the starting point, moves the resulting
/// range backward to a unit boundary (if it isn't already at one), and then tries to move |count| - 1 units backward.
/// Thus, in both cases, collapsing a nondegenerate range, whether or not moving to the start or end of the unit following
/// the collapse, counts as a unit.
///
/// The textual unit for moving.
/// The number of units to move. A positive count moves the range forward.
/// A negative count moves backward. A count of 0 has no effect.
/// The number of units actually moved, which can be less than the number requested if
/// moving the range runs into the beginning or end of the document.
public int Move(TextUnit unit, int count)
{
ValidateUnitArgument(unit, "unit");
// note: we could optimize the case of count==0 and just return 0.
return UiaCoreApi.TextRange_Move(_hTextRange, unit, count);
}
///
/// Moves one endpoint of the range the specified number of units in the text.
/// If the endpoint being moved crosses the other endpoint then the other endpoint
/// is moved along too resulting in a degenerate range and ensuring the correct ordering
/// of the endpoints. (i.e. always Start<=End)
///
/// The endpoint to move.
/// The textual unit for moving.
/// The number of units to move. A positive count moves the endpoint forward.
/// A negative count moves backward. A count of 0 has no effect.
/// The number of units actually moved, which can be less than the number requested if
/// moving the endpoint runs into the beginning or end of the document.
public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
{
ValidateEndpointArgument(endpoint, "endpoint");
ValidateUnitArgument(unit, "unit");
return UiaCoreApi.TextRange_MoveEndpointByUnit(_hTextRange, endpoint, unit, count);
}
///
/// Moves an endpoint of this range to coincide with the endpoint of another range.
///
/// The endpoint to move.
/// Another range from the same text provider.
/// An endpoint on the other range.
public void MoveEndpointByRange(TextPatternRangeEndpoint endpoint, TextPatternRange targetRange, TextPatternRangeEndpoint targetEndpoint)
{
ValidateEndpointArgument(endpoint, "endpoint");
ValidateRangeArgument(targetRange, "targetRange");
ValidateEndpointArgument(targetEndpoint, "targetEndpoint");
UiaCoreApi.TextRange_MoveEndpointByRange(_hTextRange, endpoint, targetRange._hTextRange, targetEndpoint);
}
///
/// Selects the text of the range within the provider.
///
public void Select()
{
UiaCoreApi.TextRange_Select(_hTextRange);
}
///
/// Adds the text range to the current selection.
///
public void AddToSelection()
{
UiaCoreApi.TextRange_AddToSelection(_hTextRange);
}
///
/// Removes the text range from the current selection.
///
public void RemoveFromSelection()
{
UiaCoreApi.TextRange_RemoveFromSelection(_hTextRange);
}
///
/// Scrolls the text in the provider so the range is within the viewport.
///
/// true if the provider should be scrolled so the range is flush with the top of the viewport.
/// false if the provider should be scrolled so the range is flush with the bottom.
public void ScrollIntoView(bool alignToTop)
{
UiaCoreApi.TextRange_ScrollIntoView(_hTextRange, alignToTop);
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
#region Public Properties
///
/// Retrieves a collection of all of the children that fall within the
/// range.
///
/// A collection of all children that fall within the range. Children
/// that overlap with the range but are not entirely enclosed by it will
/// also be included in the collection.
public AutomationElement[] GetChildren()
{
object[] rawChildren = UiaCoreApi.TextRange_GetChildren(_hTextRange);
AutomationElement[] wrappedChildren = new AutomationElement[rawChildren.Length];
for (int i = 0; i < rawChildren.Length; i++)
{
SafeNodeHandle hnode = UiaCoreApi.UiaHUiaNodeFromVariant(rawChildren[i]);
wrappedChildren[i] = AutomationElement.Wrap(hnode);
}
return wrappedChildren;
}
///
/// Retrieves the text provider associated with this range.
///
/// The text provider.
public TextPattern TextPattern
{
get
{
return _pattern;
}
}
#endregion Public Properties
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// check an endpoint argument to see if it is valid.
void ValidateEndpointArgument(TextPatternRangeEndpoint endpoint, string name)
{
if (endpoint != TextPatternRangeEndpoint.Start && endpoint != TextPatternRangeEndpoint.End)
{
Misc.ThrowInvalidArgument(name);
}
}
// check a range argument to see if it is valid.
void ValidateRangeArgument(TextPatternRange range, string name)
{
// check if the argument is null
if (range == null)
{
throw new ArgumentNullException(name);
}
// check if the range comes from a different text pattern.
if (!TextPattern.Compare(_pattern, range._pattern))
{
Misc.ThrowInvalidArgument(name);
}
}
// check an unit argument to see if it is valid.
void ValidateUnitArgument(TextUnit unit, string name)
{
if (unitTextUnit.Document)
{
Misc.ThrowInvalidArgument(name);
}
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
SafeTextRangeHandle _hTextRange;
TextPattern _pattern;
#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: Client-side wrapper for text range.
//
// History:
// 08/01/2003 : Micw Ported to WCP
// 02/09/2004 : a-davidj rewrote for Text Pattern redesign
// and moved to .Text subnamespace.
//
//---------------------------------------------------------------------------
// PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas.
#pragma warning disable 1634, 1691
using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Windows.Automation.Provider;
using MS.Internal.Automation;
namespace System.Windows.Automation.Text
{
// Internal Class that wraps the IntPtr to the TextRange
internal sealed class SafeTextRangeHandle : SafeHandle
{
// Called by P/Invoke when returning SafeHandles
// (Also used by UiaCoreApi to create invalid handles.)
internal SafeTextRangeHandle()
: base(IntPtr.Zero, true)
{
}
// No need to provide a finalizer - SafeHandle's critical finalizer will
// call ReleaseHandle for you.
public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}
override protected bool ReleaseHandle()
{
return UiaCoreApi.UiaTextRangeRelease(handle);
}
}
///
/// Represents a span of text in a Text Pattern container.
///
#if (INTERNAL_COMPILE)
internal class TextPatternRange
#else
public class TextPatternRange
#endif
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
internal TextPatternRange(SafeTextRangeHandle hTextRange, TextPattern pattern)
{
Debug.Assert(!hTextRange.IsInvalid);
Debug.Assert(pattern != null);
_hTextRange = hTextRange;
_pattern = pattern;
}
internal static TextPatternRange Wrap(SafeTextRangeHandle hTextRange, TextPattern pattern)
{
if (hTextRange.IsInvalid)
{
return null;
}
return new TextPatternRange(hTextRange, pattern);
}
internal static TextPatternRange [] Wrap(SafeTextRangeHandle [] hTextRanges, TextPattern pattern)
{
if (hTextRanges == null)
return null;
TextPatternRange[] ranges = new TextPatternRange[hTextRanges.Length];
for (int i = 0; i < hTextRanges.Length; i++)
{
// if invalid, leave as null
if (!hTextRanges[i].IsInvalid)
{
ranges[i] = new TextPatternRange(hTextRanges[i], pattern);
}
}
return ranges;
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
///
/// Retrieves a new range covering an identical span of text. The new range can be manipulated independently from the original.
///
/// The new range.
public TextPatternRange Clone()
{
SafeTextRangeHandle hResultTextRange = UiaCoreApi.TextRange_Clone(_hTextRange);
return Wrap(hResultTextRange, _pattern);
}
///
/// Compares this range with another range.
///
/// A range to compare.
/// The range must have come from the same text provider or an InvalidArgumentException will be thrown.
/// true if both ranges span the same text.
public bool Compare(TextPatternRange range)
{
ValidateRangeArgument(range, "range");
return UiaCoreApi.TextRange_Compare(_hTextRange, range._hTextRange);
}
///
/// Compares the endpoint of this range with the endpoint of another range.
///
/// The endpoint of this range to compare.
/// The range with the other endpoint to compare.
/// The range must have come from the same text provider or an InvalidArgumentException will be thrown.
/// The endpoint on the other range to compare.
/// Returns <0 if this endpoint occurs earlier in the text than the target endpoint.
/// Returns 0 if this endpoint is at the same location as the target endpoint.
/// Returns >0 if this endpoint occurs later in the text than the target endpoint.
public int CompareEndpoints(TextPatternRangeEndpoint endpoint, TextPatternRange targetRange, TextPatternRangeEndpoint targetEndpoint)
{
ValidateEndpointArgument(endpoint, "endpoint");
ValidateRangeArgument(targetRange, "targetRange");
ValidateEndpointArgument(targetEndpoint, "targetEndpoint");
return UiaCoreApi.TextRange_CompareEndpoints(_hTextRange, endpoint, targetRange._hTextRange, targetEndpoint);
}
///
/// Expands the range to an integral number of enclosing units. This could be used, for example,
/// to guarantee that a range endpoint is not in the middle of a word. If the range is already an
/// integral number of the specified units then it remains unchanged.
/// For the TextUnit.Word unit with a degenerate range if the range is immediately before a word,
/// inside that word, or within the whitespace following that word (but not immediately before the next
/// word) then it will expand to include that word.
/// For the TextUnit.Format unit if the range has mixed formatting then the range starting point will
/// be moved backwards over any text that is identically formatted to that at the start of the range
/// and the endpoint will be move forwards over any text that is identically formatted to that at the
/// end of the range.
///
/// The textual unit.
public void ExpandToEnclosingUnit(TextUnit unit)
{
ValidateUnitArgument(unit, "unit");
UiaCoreApi.TextRange_ExpandToEnclosingUnit(_hTextRange, unit);
}
///
/// Searches for a subrange of text that has the specified attribute.
/// To search the entire document use the text pattern's document range.
///
/// The attribute to search for.
/// The value of the specified attribute to search for. The value must be of the exact type specified for the
/// attribute. For example when searching for font size you must specify the size in points as a double.
/// If you specify the point size as an integer then you will never get any matches due to the differing types.
/// true if the last occurring range should be returned instead of the first.
/// A subrange with the specified attribute, or null if no such subrange exists.
public TextPatternRange FindAttribute(AutomationTextAttribute attribute, object value, bool backward)
{
Misc.ValidateArgumentNonNull(attribute, "attribute");
Misc.ValidateArgumentNonNull(value, "value"); // no text attributes can have null as a valid value
// Check that attribute value is of expected type...
AutomationAttributeInfo ai;
if(!Schema.GetAttributeInfo(attribute, out ai))
{
throw new ArgumentException(SR.Get(SRID.UnsupportedAttribute));
}
if (value.GetType() != ai.Type)
{
throw new ArgumentException(SR.Get(SRID.TextAttributeValueWrongType, attribute, ai.Type.Name, value.GetType().Name), "value");
}
// note: if we implement attributes whose values are logical elements, patterns,
// or ranges then we'll need to unwrap the objects here before passing them on to
// the provider.
if (attribute == TextPattern.CultureAttribute)
{
if (value is CultureInfo)
{
value = ((CultureInfo)value).LCID;
}
}
SafeTextRangeHandle hResultTextRange = UiaCoreApi.TextRange_FindAttribute(_hTextRange, attribute.Id, value, backward);
return Wrap(hResultTextRange, _pattern);
}
///
/// Searches for an occurrence of text within the range.
///
/// The text to search for.
/// true if the last occurring range should be returned instead of the first.
/// true if case should be ignored for the purposes of comparison.
/// A subrange with the specified text, or null if no such subrange exists.
public TextPatternRange FindText(string text, bool backward, bool ignoreCase)
{
// PerSharp/PreFast will flag this as warning 6507/56507: Prefer 'string.IsNullOrEmpty(text)' over checks for null and/or emptiness.
// A null string is not should throw an ArgumentNullException while an empty string should throw an ArgumentException.
// Therefore we can not use IsNullOrEmpty() here, suppress the warning.
Misc.ValidateArgumentNonNull(text, "text");
#pragma warning suppress 6507
Misc.ValidateArgument(text.Length != 0, SRID.TextMustNotBeNullOrEmpty);
SafeTextRangeHandle hResultTextRange = UiaCoreApi.TextRange_FindText(_hTextRange, text, backward, ignoreCase);
return Wrap(hResultTextRange, _pattern);
}
///
/// Retrieves the value of a text attribute over the entire range.
///
/// The text attribute.
/// The value of the attribute across the range.
/// If the attribute's value varies over the range then the value is TextPattern.MixedAttributeValue
public object GetAttributeValue(AutomationTextAttribute attribute)
{
Misc.ValidateArgumentNonNull(attribute, "attribute");
AutomationAttributeInfo ai;
if(!Schema.GetAttributeInfo(attribute, out ai))
{
throw new ArgumentException(SR.Get(SRID.UnsupportedAttribute));
}
object obj = UiaCoreApi.TextRange_GetAttributeValue(_hTextRange, attribute.Id);
if (ai.Type.IsEnum && obj is int)
{
// Convert ints from COM Interop to the appropriate enum type
obj = Enum.ToObject(ai.Type, (int)obj);
}
else if (obj != AutomationElement.NotSupported && ai.ObjectConverter != null)
{
// Use a custom converter, if needed (eg. converts LCIDs to CultureInfo)
obj = ai.ObjectConverter(obj);
}
return obj;
}
///
/// Retrieves the bounding rectangles for viewable lines of the range.
///
/// An array of bounding rectangles for each line or portion of a line within the client area of the text provider.
/// No bounding rectangles will be returned for lines that are empty or scrolled out of view. Note that even though a
/// bounding rectangle is returned the corresponding text may not be visible due to overlapping windows.
/// This will not return null, but may return an empty array.
public Rect[] GetBoundingRectangles()
{
return UiaCoreApi.TextRange_GetBoundingRectangles(_hTextRange);
}
///
/// Retrieves the innermost element that encloses this range.
///
/// An element. Usually this element will be the one that supplied this range.
/// However, if the text provider supports child elements such as tables or hyperlinks, then the
/// enclosing element could be a descendant element of the text provider.
///
public AutomationElement GetEnclosingElement()
{
return AutomationElement.Wrap(UiaCoreApi.TextRange_GetEnclosingElement(_hTextRange));
}
///
/// Retrieves the text of the range.
///
/// Specifies the maximum length of the string to return or -1 if no limit is requested.
/// The text of the range possibly truncated to the specified limit.
public string GetText(int maxLength)
{
Misc.ValidateArgumentInRange(maxLength >= -1, "maxLength");
return UiaCoreApi.TextRange_GetText(_hTextRange, maxLength);
}
///
/// Moves the range the specified number of units in the text. Note that the text is not altered. Instead the
/// range spans a different part of the text.
/// If the range is degenerate, this method tries to move the insertion point count units. If the range is nondegenerate
/// and count is greater than zero, this method collapses the range at its end point, moves the resulting range forward
/// to a unit boundary (if it is not already at one), and then tries to move count - 1 units forward. If the range is
/// nondegenerate and count is less than zero, this method collapses the range at the starting point, moves the resulting
/// range backward to a unit boundary (if it isn't already at one), and then tries to move |count| - 1 units backward.
/// Thus, in both cases, collapsing a nondegenerate range, whether or not moving to the start or end of the unit following
/// the collapse, counts as a unit.
///
/// The textual unit for moving.
/// The number of units to move. A positive count moves the range forward.
/// A negative count moves backward. A count of 0 has no effect.
/// The number of units actually moved, which can be less than the number requested if
/// moving the range runs into the beginning or end of the document.
public int Move(TextUnit unit, int count)
{
ValidateUnitArgument(unit, "unit");
// note: we could optimize the case of count==0 and just return 0.
return UiaCoreApi.TextRange_Move(_hTextRange, unit, count);
}
///
/// Moves one endpoint of the range the specified number of units in the text.
/// If the endpoint being moved crosses the other endpoint then the other endpoint
/// is moved along too resulting in a degenerate range and ensuring the correct ordering
/// of the endpoints. (i.e. always Start<=End)
///
/// The endpoint to move.
/// The textual unit for moving.
/// The number of units to move. A positive count moves the endpoint forward.
/// A negative count moves backward. A count of 0 has no effect.
/// The number of units actually moved, which can be less than the number requested if
/// moving the endpoint runs into the beginning or end of the document.
public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
{
ValidateEndpointArgument(endpoint, "endpoint");
ValidateUnitArgument(unit, "unit");
return UiaCoreApi.TextRange_MoveEndpointByUnit(_hTextRange, endpoint, unit, count);
}
///
/// Moves an endpoint of this range to coincide with the endpoint of another range.
///
/// The endpoint to move.
/// Another range from the same text provider.
/// An endpoint on the other range.
public void MoveEndpointByRange(TextPatternRangeEndpoint endpoint, TextPatternRange targetRange, TextPatternRangeEndpoint targetEndpoint)
{
ValidateEndpointArgument(endpoint, "endpoint");
ValidateRangeArgument(targetRange, "targetRange");
ValidateEndpointArgument(targetEndpoint, "targetEndpoint");
UiaCoreApi.TextRange_MoveEndpointByRange(_hTextRange, endpoint, targetRange._hTextRange, targetEndpoint);
}
///
/// Selects the text of the range within the provider.
///
public void Select()
{
UiaCoreApi.TextRange_Select(_hTextRange);
}
///
/// Adds the text range to the current selection.
///
public void AddToSelection()
{
UiaCoreApi.TextRange_AddToSelection(_hTextRange);
}
///
/// Removes the text range from the current selection.
///
public void RemoveFromSelection()
{
UiaCoreApi.TextRange_RemoveFromSelection(_hTextRange);
}
///
/// Scrolls the text in the provider so the range is within the viewport.
///
/// true if the provider should be scrolled so the range is flush with the top of the viewport.
/// false if the provider should be scrolled so the range is flush with the bottom.
public void ScrollIntoView(bool alignToTop)
{
UiaCoreApi.TextRange_ScrollIntoView(_hTextRange, alignToTop);
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
#region Public Properties
///
/// Retrieves a collection of all of the children that fall within the
/// range.
///
/// A collection of all children that fall within the range. Children
/// that overlap with the range but are not entirely enclosed by it will
/// also be included in the collection.
public AutomationElement[] GetChildren()
{
object[] rawChildren = UiaCoreApi.TextRange_GetChildren(_hTextRange);
AutomationElement[] wrappedChildren = new AutomationElement[rawChildren.Length];
for (int i = 0; i < rawChildren.Length; i++)
{
SafeNodeHandle hnode = UiaCoreApi.UiaHUiaNodeFromVariant(rawChildren[i]);
wrappedChildren[i] = AutomationElement.Wrap(hnode);
}
return wrappedChildren;
}
///
/// Retrieves the text provider associated with this range.
///
/// The text provider.
public TextPattern TextPattern
{
get
{
return _pattern;
}
}
#endregion Public Properties
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// check an endpoint argument to see if it is valid.
void ValidateEndpointArgument(TextPatternRangeEndpoint endpoint, string name)
{
if (endpoint != TextPatternRangeEndpoint.Start && endpoint != TextPatternRangeEndpoint.End)
{
Misc.ThrowInvalidArgument(name);
}
}
// check a range argument to see if it is valid.
void ValidateRangeArgument(TextPatternRange range, string name)
{
// check if the argument is null
if (range == null)
{
throw new ArgumentNullException(name);
}
// check if the range comes from a different text pattern.
if (!TextPattern.Compare(_pattern, range._pattern))
{
Misc.ThrowInvalidArgument(name);
}
}
// check an unit argument to see if it is valid.
void ValidateUnitArgument(TextUnit unit, string name)
{
if (unitTextUnit.Document)
{
Misc.ThrowInvalidArgument(name);
}
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
SafeTextRangeHandle _hTextRange;
TextPattern _pattern;
#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
- LocatorPartList.cs
- IEnumerable.cs
- DocumentSchemaValidator.cs
- ReadOnlyTernaryTree.cs
- shaperfactoryquerycachekey.cs
- ServiceNameCollection.cs
- UIElementParaClient.cs
- SettingsSection.cs
- SecurityProtocol.cs
- _NTAuthentication.cs
- SafeArrayRankMismatchException.cs
- Matrix.cs
- TextDataBindingHandler.cs
- MembershipUser.cs
- EventEntry.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- Point3DAnimationBase.cs
- DataBindingCollectionEditor.cs
- GCHandleCookieTable.cs
- XmlSerializerSection.cs
- RtfControls.cs
- ZoomPercentageConverter.cs
- Simplifier.cs
- PersonalizationEntry.cs
- XmlDataCollection.cs
- PathBox.cs
- HtmlElementEventArgs.cs
- AssemblyCache.cs
- ValueConversionAttribute.cs
- ConfigXmlText.cs
- DnsPermission.cs
- TextAdaptor.cs
- RoleManagerEventArgs.cs
- IFlowDocumentViewer.cs
- MexHttpBindingElement.cs
- UnmanagedHandle.cs
- PresentationUIStyleResources.cs
- SpanIndex.cs
- JournalEntryStack.cs
- HandlerWithFactory.cs
- BitmapEffect.cs
- WebServiceReceive.cs
- StrokeFIndices.cs
- XsltArgumentList.cs
- TypeGeneratedEventArgs.cs
- DataView.cs
- UnsafeNativeMethods.cs
- DiffuseMaterial.cs
- OleCmdHelper.cs
- HttpResponse.cs
- AuthorizationContext.cs
- CubicEase.cs
- CellConstantDomain.cs
- HostDesigntimeLicenseContext.cs
- TextComposition.cs
- ValidatorCollection.cs
- NumberSubstitution.cs
- RemoteWebConfigurationHostServer.cs
- ScrollBar.cs
- CheckedListBox.cs
- SqlIdentifier.cs
- ParenExpr.cs
- AssemblyCollection.cs
- WebServiceData.cs
- FormClosingEvent.cs
- CustomAttribute.cs
- PkcsUtils.cs
- SeekableReadStream.cs
- COM2ColorConverter.cs
- CombinedGeometry.cs
- MobileControlsSection.cs
- SeverityFilter.cs
- SiteMapPath.cs
- BuildManagerHost.cs
- PathFigure.cs
- HttpCacheVary.cs
- FastEncoder.cs
- WindowsSpinner.cs
- BindableTemplateBuilder.cs
- DataColumnPropertyDescriptor.cs
- CompilationRelaxations.cs
- WeakReadOnlyCollection.cs
- InkCanvasInnerCanvas.cs
- PathTooLongException.cs
- ServiceObjectContainer.cs
- DataGridPagerStyle.cs
- PtsCache.cs
- TextSegment.cs
- ElementInit.cs
- NetTcpSecurity.cs
- ErrorHandler.cs
- BlurEffect.cs
- DataGridViewColumnConverter.cs
- Stack.cs
- ServiceBusyException.cs
- ProfileProvider.cs
- TextElement.cs
- NameValueCache.cs
- ProfilePropertyMetadata.cs
- AddInEnvironment.cs