Partager via


Accéder au texte à l'aide d'UI Automation

RemarqueRemarque

Cette documentation s'adresse aux développeurs .NET Framework qui veulent utiliser les classes UI Automation managées définies dans l'espace de noms System.Windows.Automation.Pour obtenir les informations les plus récentes sur UI Automation, consultez API Windows Automation : UI Automation (page éventuellement en anglais).

Cette rubrique montre comment utiliser Microsoft UI Automation pour accéder au contenu textuel d'un document par incréments TextUnit.

Exemple

L'exemple de code suivant montre comment accéder au contenu d'un fournisseur de texte UI Automation. La méthode Move déplace les points de terminaison Start et End d'un TextPatternRange. En général, cette plage de texte est une plage dégénérée représentant le point d'insertion de texte.

RemarqueRemarque

Étant donné que seuls les objets incorporés textuels sont considérés comme appartenant au flux de texte, les objets incorporés tels que les images n'affectent pas Move ou sa valeur de retour.

'--------------------------------------------------------------------
' <summary>
' Starts the target application.
' </summary>
' <param name="app">
' The application to start.
' </param>
' <returns>The automation element for the app main window.</returns>
' <remarks>
' Three WPF documents, a rich text document, and a plain text document 
' are provided in the Content folder of the TextProvider project.
' </remarks>
'--------------------------------------------------------------------
Private Function StartApp(ByVal app As String) As AutomationElement
    ' Start application.
    Dim p As Process = Process.Start(app)

    ' Give the target application some time to start.
    ' For Win32 applications, WaitForInputIdle can be used instead.
    ' Another alternative is to listen for WindowOpened events.
    ' Otherwise, an ArgumentException results when you try to
    ' retrieve an automation element from the window handle.
    Thread.Sleep(2000)

    targetResult.Content = WPFTarget + " started. " + vbLf + vbLf + _
    "Please load a document into the target application and click " + _
    "the 'Find edit control' button above. " + vbLf + vbLf + _
    "NOTE: Documents can be found in the 'Content' folder of the FindText project."
    targetResult.Background = Brushes.LightGreen

    ' Return the automation element for the app main window.
    Return AutomationElement.FromHandle(p.MainWindowHandle)

End Function 'StartApp


...


'--------------------------------------------------------------------
' <summary>
' Finds the text control in our target.
' </summary>
' <param name="src">The object that raised the event.</param>
' <param name="e">Event arguments.</param>
' <remarks>
' Initializes the TextPattern object and event handlers.
' </remarks>
'--------------------------------------------------------------------
Private Sub FindTextProvider_Click( _
ByVal src As Object, ByVal e As RoutedEventArgs)
    ' Set up the conditions for finding the text control.
    Dim documentControl As New PropertyCondition( _
    AutomationElement.ControlTypeProperty, ControlType.Document)
    Dim textPatternAvailable As New PropertyCondition( _
    AutomationElement.IsTextPatternAvailableProperty, True)
    Dim findControl As New AndCondition(documentControl, textPatternAvailable)

    ' Get the Automation Element for the first text control found.
    ' For the purposes of this sample it is sufficient to find the 
    ' first text control. In other cases there may be multiple text
    ' controls to sort through.
    targetDocument = targetWindow.FindFirst(TreeScope.Descendants, findControl)

    ' Didn't find a text control.
    If targetDocument Is Nothing Then
        targetResult.Content = _
        WPFTarget + " does not contain a Document control type."
        targetResult.Background = Brushes.Salmon
        startWPFTargetButton.IsEnabled = False
        Return
    End If

    ' Get required control patterns 
    targetTextPattern = DirectCast( _
    targetDocument.GetCurrentPattern(TextPattern.Pattern), TextPattern)

    ' Didn't find a text control that supports TextPattern.
    If targetTextPattern Is Nothing Then
        targetResult.Content = WPFTarget + _
        " does not contain an element that supports TextPattern."
        targetResult.Background = Brushes.Salmon
        startWPFTargetButton.IsEnabled = False
        Return
    End If
    ' Text control is available so display the client controls.
    infoGrid.Visibility = Visibility.Visible

    targetResult.Content = "Text provider found."
    targetResult.Background = Brushes.LightGreen

    ' Initialize the document range for the text of the document.
    documentRange = targetTextPattern.DocumentRange

    ' Initialize the client's search buttons.
    If targetTextPattern.DocumentRange.GetText(1).Length > 0 Then
        searchForwardButton.IsEnabled = True
    End If
    ' Initialize the client's search TextBox.
    searchString.IsEnabled = True

    ' Check if the text control supports text selection
    If targetTextPattern.SupportedTextSelection = SupportedTextSelection.None Then
        targetResult.Content = "Unable to select text."
        targetResult.Background = Brushes.Salmon
        Return
    End If

    ' Edit control found so remove the find button from the client.
    findEditButton.Visibility = Visibility.Collapsed

    ' Initialize the client with the current target selection, if any.
    NotifySelectionChanged()

    ' Search starts at beginning of doc and goes forward
    searchBackward = False

    ' Initialize a text changed listener.
    ' An instance of TextPatternRange will become invalid if 
    ' one of the following occurs:
    ' 1) The text in the provider changes via some user activity.
    ' 2) ValuePattern.SetValue is used to programatically change 
    ' the value of the text in the provider.
    ' The only way the client application can detect if the text 
    ' has changed (to ensure that the ranges are still valid), 
    ' is by setting a listener for the TextChanged event of 
    ' the TextPattern. If this event is raised, the client needs 
    ' to update the targetDocumentRange member data to ensure the 
    ' user is working with the updated text. 
    ' Clients must always anticipate the possibility that the text 
    ' can change underneath them.
    Dim onTextChanged As AutomationEventHandler = _
    New AutomationEventHandler(AddressOf TextChanged)
    Automation.AddAutomationEventHandler( _
    TextPattern.TextChangedEvent, targetDocument, TreeScope.Element, onTextChanged)
    ' Initialize a selection changed listener.
    ' The target selection is reflected in the client.
    Dim onSelectionChanged As AutomationEventHandler = _
    New AutomationEventHandler(AddressOf OnTextSelectionChange)
    Automation.AddAutomationEventHandler( _
    TextPattern.TextSelectionChangedEvent, targetDocument, _
    TreeScope.Element, onSelectionChanged)

End Sub 'FindTextProvider_Click


...


'--------------------------------------------------------------------
' <summary>
' Handles the navigation item selected event.
' </summary>
' <param name="sender">The object that raised the event.</param>
' <param name="e">Event arguments.</param>
'--------------------------------------------------------------------
Private Sub NavigationUnit_Change( _
ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
    Dim cb As ComboBox = CType(sender, ComboBox)
    navigationUnit = CType(cb.SelectedValue, TextUnit)

End Sub 'NavigationUnit_Change

'--------------------------------------------------------------------
' <summary>
' Handles the Navigate button click event.
' </summary>
' <param name="sender">The object that raised the event.</param>
' <param name="e">Event arguments.</param>
'--------------------------------------------------------------------
Private Sub Navigate_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim moveSelection As Button = CType(sender, Button)
    Dim navDirection As Integer

    ' Which direction is the user searching through the text control?
    If (CType(moveSelection.Tag, traversalDirection) = traversalDirection.Forward) Then
        navDirection = 1
    Else
        navDirection = -1
    End If

    ' Obtain the ranges to move.
    Dim selectionRanges As TextPatternRange() = targetTextPattern.GetSelection()

    ' Iterate throught the ranges for a text control that supports
    ' multiple selections and move the selections the specified text
    ' unit and direction.
    Dim textRange As TextPatternRange
    For Each textRange In selectionRanges
        textRange.Move(navigationUnit, navDirection)
        textRange.Select()
    Next textRange
    ' The WPF target doesn't show selected text as highlighted unless
    ' the window has focus.
    targetDocument.SetFocus()

End Sub 'Navigate_Click
///--------------------------------------------------------------------
/// <summary>
/// Starts the target application.
/// </summary>
/// <param name="app">
/// The application to start.
/// </param>
/// <returns>The automation element for the app main window.</returns>
/// <remarks>
/// Three WPF documents, a rich text document, and a plain text document 
/// are provided in the Content folder of the TextProvider project.
/// </remarks>
///--------------------------------------------------------------------
private AutomationElement StartApp(string app)
{
    // Start application.
    Process p = Process.Start(app);

    // Give the target application some time to start.
    // For Win32 applications, WaitForInputIdle can be used instead.
    // Another alternative is to listen for WindowOpened events.
    // Otherwise, an ArgumentException results when you try to
    // retrieve an automation element from the window handle.
    Thread.Sleep(2000);

    targetResult.Content =
        WPFTarget +
        " started. \n\nPlease load a document into the target " +
        "application and click the 'Find edit control' button above. " +
        "\n\nNOTE: Documents can be found in the 'Content' folder of the FindText project.";
    targetResult.Background = Brushes.LightGreen;

    // Return the automation element for the app main window.
    return (AutomationElement.FromHandle(p.MainWindowHandle));
}


...


///--------------------------------------------------------------------
/// <summary>
/// Finds the text control in our target.
/// </summary>
/// <param name="src">The object that raised the event.</param>
/// <param name="e">Event arguments.</param>
/// <remarks>
/// Initializes the TextPattern object and event handlers.
/// </remarks>
///--------------------------------------------------------------------
private void FindTextProvider_Click(object src, RoutedEventArgs e)
{
    // Set up the conditions for finding the text control.
    PropertyCondition documentControl = new PropertyCondition(
        AutomationElement.ControlTypeProperty,
        ControlType.Document);
    PropertyCondition textPatternAvailable = new PropertyCondition(
        AutomationElement.IsTextPatternAvailableProperty, true);
    AndCondition findControl =
        new AndCondition(documentControl, textPatternAvailable);

    // Get the Automation Element for the first text control found.
    // For the purposes of this sample it is sufficient to find the 
    // first text control. In other cases there may be multiple text
    // controls to sort through.
    targetDocument =
        targetWindow.FindFirst(TreeScope.Descendants, findControl);

    // Didn't find a text control.
    if (targetDocument == null)
    {
        targetResult.Content =
            WPFTarget +
            " does not contain a Document control type.";
        targetResult.Background = Brushes.Salmon;
        startWPFTargetButton.IsEnabled = false;
        return;
    }

    // Get required control patterns 
    targetTextPattern =
        targetDocument.GetCurrentPattern(
        TextPattern.Pattern) as TextPattern;

    // Didn't find a text control that supports TextPattern.
    if (targetTextPattern == null)
    {
        targetResult.Content =
            WPFTarget +
            " does not contain an element that supports TextPattern.";
        targetResult.Background = Brushes.Salmon;
        startWPFTargetButton.IsEnabled = false;
        return;
    }

    // Text control is available so display the client controls.
    infoGrid.Visibility = Visibility.Visible;

    targetResult.Content =
        "Text provider found.";
    targetResult.Background = Brushes.LightGreen;

    // Initialize the document range for the text of the document.
    documentRange = targetTextPattern.DocumentRange;

    // Initialize the client's search buttons.
    if (targetTextPattern.DocumentRange.GetText(1).Length > 0)
    {
        searchForwardButton.IsEnabled = true;
    }
    // Initialize the client's search TextBox.
    searchString.IsEnabled = true;

    // Check if the text control supports text selection
    if (targetTextPattern.SupportedTextSelection ==
        SupportedTextSelection.None)
    {
        targetResult.Content = "Unable to select text.";
        targetResult.Background = Brushes.Salmon;
        return;
    }

    // Edit control found so remove the find button from the client.
    findEditButton.Visibility = Visibility.Collapsed;

    // Initialize the client with the current target selection, if any.
    NotifySelectionChanged();

    // Search starts at beginning of doc and goes forward
    searchBackward = false;

    // Initialize a text changed listener.
    // An instance of TextPatternRange will become invalid if 
    // one of the following occurs:
    // 1) The text in the provider changes via some user activity.
    // 2) ValuePattern.SetValue is used to programatically change 
    // the value of the text in the provider.
    // The only way the client application can detect if the text 
    // has changed (to ensure that the ranges are still valid), 
    // is by setting a listener for the TextChanged event of 
    // the TextPattern. If this event is raised, the client needs 
    // to update the targetDocumentRange member data to ensure the 
    // user is working with the updated text. 
    // Clients must always anticipate the possibility that the text 
    // can change underneath them.
    Automation.AddAutomationEventHandler(
        TextPattern.TextChangedEvent,
        targetDocument,
        TreeScope.Element,
        TextChanged);

    // Initialize a selection changed listener.
    // The target selection is reflected in the client.
    Automation.AddAutomationEventHandler(
        TextPattern.TextSelectionChangedEvent,
        targetDocument,
        TreeScope.Element,
        OnTextSelectionChange);
}


...


///--------------------------------------------------------------------
/// <summary>
/// Handles the navigation item selected event.
/// </summary>
/// <param name="sender">The object that raised the event.</param>
/// <param name="e">Event arguments.</param>
///--------------------------------------------------------------------
private void NavigationUnit_Change(object sender, SelectionChangedEventArgs e)
{
    ComboBox cb = (ComboBox)sender;
    navigationUnit = (TextUnit)cb.SelectedValue;
}

///--------------------------------------------------------------------
/// <summary>
/// Handles the Navigate button click event.
/// </summary>
/// <param name="sender">The object that raised the event.</param>
/// <param name="e">Event arguments.</param>
///--------------------------------------------------------------------
private void Navigate_Click(object sender, RoutedEventArgs e)
{
    Button moveSelection = (Button)sender;

    // Which direction is the user searching through the text control?
    int navDirection =
        ((traversalDirection)moveSelection.Tag == traversalDirection.Forward) ? 1 : -1;            

    // Obtain the ranges to move.
    TextPatternRange[] selectionRanges =
                   targetTextPattern.GetSelection();

    // Iterate throught the ranges for a text control that supports
    // multiple selections and move the selections the specified text
    // unit and direction.
    foreach (TextPatternRange textRange in selectionRanges)
    {
        textRange.Move(navigationUnit, navDirection);
        textRange.Select();
   }
   // The WPF target doesn't show selected text as highlighted unless
   // the window has focus.
   targetDocument.SetFocus();
}

Toute méthode utilisant TextUnit défère au TextUnit pris en charge suivant le plus long si le TextUnit concerné n'est pas pris en charge par le contrôle.

Voir aussi

Tâches

Ajouter du contenu à une zone de texte à l'aide d'UI Automation

Rechercher et mettre un texte en surbrillance à l'aide d'UI Automation

Concepts

Vue d'ensemble de TextPattern d'UI Automation

Vue d'ensemble des modèles de contrôle UI Automation

Modèles de contrôle UI Automation pour les clients