Share via


Obtain Text Attributes Using UI Automation

This topic shows how to use Microsoft UI Automation to obtain text attributes from a text range. A text range can correspond to the current location of the caret (or degenerate selection) within a document, a contiguous selection of text, a collection of disjoint text selections, or the entire textual content of a document.

Example

The following code example demonstrates how to obtain the FontNameAttribute from a text range.

    ''' -------------------------------------------------------------------
    ''' <summary>
    ''' Starts the target application and returns the AutomationElement 
    ''' obtained from the targets window handle.
    ''' </summary>
    ''' <param name="exe">
    ''' The target application.
    ''' </param>
    ''' <param name="filename">
    ''' The text file to be opened in the target application
    ''' </param>
    ''' <returns>
    ''' An AutomationElement representing the target application.
    ''' </returns>
    ''' -------------------------------------------------------------------
    Private Function StartTarget( _
    ByVal exe As String, ByVal filename As String) As AutomationElement
        ' Start text editor and load with a text file.
        Dim p As Process = Process.Start(exe, filename)

        ' targetApp --> the root AutomationElement.
        Dim targetApp As AutomationElement
        targetApp = AutomationElement.FromHandle(p.MainWindowHandle)

        Return targetApp
    End Function

...

    ''' -------------------------------------------------------------------
    ''' <summary>
    ''' Obtain the text control of interest from the target application.
    ''' </summary>
    ''' <param name="targetApp">
    ''' The target application.
    ''' </param>
    ''' <returns>
    ''' An AutomationElement. representing a text control.
    ''' </returns>
    ''' -------------------------------------------------------------------
    Private Function GetTextElement(ByVal targetApp As AutomationElement) As AutomationElement
        ' The control type we're looking for; in this case 'Document'
        Dim cond1 As PropertyCondition = _
            New PropertyCondition( _
            AutomationElement.ControlTypeProperty, _
            ControlType.Document)

        ' The control pattern of interest; in this case 'TextPattern'.
        Dim cond2 As PropertyCondition = _
            New PropertyCondition( _
            AutomationElement.IsTextPatternAvailableProperty, _
            True)

        Dim textCondition As AndCondition = New AndCondition(cond1, cond2)

        Dim targetTextElement As AutomationElement = _
            targetApp.FindFirst(TreeScope.Descendants, textCondition)

        ' If targetText is null then a suitable text control was not found.
        Return targetTextElement
    End Function

...

    ''' -------------------------------------------------------------------
    ''' <summary>
    ''' Outputs the FontNameAttribute value for a range of text.
    ''' </summary>
    ''' <param name="targetTextElement">
    ''' The AutomationElement. that represents the text provider.
    ''' </param>
    ''' -------------------------------------------------------------------
    Private Sub GetFontNameAttribute( _
    ByVal targetTextElement As AutomationElement)
        Dim targetTextPattern As TextPattern = _
            DirectCast(targetTextElement.GetCurrentPattern( _
            TextPattern.Pattern), TextPattern)

        If (targetTextPattern Is Nothing) Then
            ' Target control doesn't support TextPattern.
            Return
        End If

        ' If the target control doesn't support selection then return.
        ' Otherwise, get the text attribute for the selected text.
        ' If there are currently no selections then the text attribute 
        ' will be obtained from the insertion point.
        Dim textRanges() As TextPatternRange
        If (targetTextPattern.SupportedTextSelection = SupportedTextSelection.None) Then
            Return
        Else
            textRanges = targetTextPattern.GetSelection()
        End If

        Dim textRange As TextPatternRange
        For Each textRange In textRanges
            Dim textAttribute As Object = _
                textRange.GetAttributeValue( _
                TextPattern.FontNameAttribute)

            If (textAttribute = TextPattern.MixedAttributeValue) Then
                ' Returns MixedAttributeValue if the value of the 
                ' specified attribute varies over the text range. 
                Console.WriteLine("Mixed fonts.")
            ElseIf (textAttribute = AutomationElement.NotSupported) Then
                ' Returns NotSupported if the specified attribute is 
                ' not supported by the provider or the control. 
                Console.WriteLine( _
                "FontNameAttribute not supported by provider.")
            Else
                Console.WriteLine(textAttribute.ToString())
            End If
        Next
    End Sub
    /// -------------------------------------------------------------------
    /// <summary>
    /// Starts the target application and returns the AutomationElement 
    /// obtained from the targets window handle.
    /// </summary>
    /// <param name="exe">
    /// The target application.
    /// </param>
    /// <param name="filename">
    /// The text file to be opened in the target application
    /// </param>
    /// <returns>
    /// An AutomationElement representing the target application.
    /// </returns>
    /// -------------------------------------------------------------------
    private AutomationElement StartTarget(string exe, string filename)
    {
        // Start text editor and load with a text file.
        Process p = Process.Start(exe, filename);

        // targetApp --> the root AutomationElement.
        AutomationElement targetApp =
            AutomationElement.FromHandle(p.MainWindowHandle);

        return targetApp;
    }

...

    /// -------------------------------------------------------------------
    /// <summary>
    /// Obtain the text control of interest from the target application.
    /// </summary>
    /// <param name="targetApp">
    /// The target application.
    /// </param>
    /// <returns>
    /// An AutomationElement that represents a text provider..
    /// </returns>
    /// -------------------------------------------------------------------
    private AutomationElement GetTextElement(AutomationElement targetApp)
    {
        // The control type we're looking for; in this case 'Document'
        PropertyCondition cond1 =
            new PropertyCondition(
            AutomationElement.ControlTypeProperty,
            ControlType.Document);

        // The control pattern of interest; in this case 'TextPattern'.
        PropertyCondition cond2 = 
            new PropertyCondition(
            AutomationElement.IsTextPatternAvailableProperty, 
            true);

        AndCondition textCondition = new AndCondition(cond1, cond2);

        AutomationElement targetTextElement =
            targetApp.FindFirst(TreeScope.Descendants, textCondition);

        // If targetText is null then a suitable text control was not found.
        return targetTextElement;
    }

...

    /// -------------------------------------------------------------------
    /// <summary>
    /// Outputs the FontNameAttribute value for a range of text.
    /// </summary>
    /// <param name="targetTextElement">
    /// The AutomationElment that represents a text control.
    /// </param>
    /// -------------------------------------------------------------------
    private void GetFontNameAttribute(AutomationElement targetTextElement)
    {
        TextPattern textPattern = 
            targetTextElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern;

        if (textPattern == null)
        {
            // Target control doesn't support TextPattern.
            return;
        }

        // If the target control doesn't support selection then return.
        // Otherwise, get the text attribute for the selected text.
        // If there are currently no selections then the text attribute 
        // will be obtained from the insertion point.
        TextPatternRange[] textRanges;
        if (textPattern.SupportedTextSelection == SupportedTextSelection.None)
        {
            return;
        }
        else
        {
            textRanges = textPattern.GetSelection();
        }

        foreach (TextPatternRange textRange in textRanges)
        {
            Object textAttribute =
                textRange.GetAttributeValue(
                TextPattern.FontNameAttribute);

            if (textAttribute == TextPattern.MixedAttributeValue)
            {
                // Returns MixedAttributeValue if the value of the 
                // specified attribute varies over the text range. 
                Console.WriteLine("Mixed fonts.");
            }
            else if (textAttribute == AutomationElement.NotSupported)
            {
                // Returns NotSupported if the specified attribute is 
                // not supported by the provider or the control. 
                Console.WriteLine(
                    "FontNameAttribute not supported by provider.");
            }
            else
            {
                Console.WriteLine(textAttribute.ToString());
            }
        }
    }

The TextPattern control pattern, in tandem with the TextPatternRange class, supports basic text attributes, properties, and methods. For control-specific functionality that is not supported by TextPattern or TextPatternRange the AutomationElement class provides methods for a UI Automation client to access the corresponding native object model.

See Also

Tasks

Add Content to a Text Box Using UI Automation
Find and Highlight Text Using UI Automation

Concepts

UI Automation TextPattern Overview
UI Automation Control Patterns Overview
UI Automation Control Patterns for Clients