Move a UI Automation Element

This example demonstrates how to move a UI Automation element to a specified screen location.

Example

The following example uses the WindowPattern and TransformPattern control patterns to programmatically move a Win32 target application to discrete screen locations and track the BoundingRectangleProperty AutomationPropertyChangedEvent.

    '' <summary>
    '' The Startup handler.
    '' </summary>
    '' <param name="e">The event arguments</param>
    Protected Overrides Sub OnStartup(ByVal e As StartupEventArgs)

        ' Start the WindowMove client.
        CreateWindow()

        Try
            ' Obtain an AutomationElement from the target window handle.
            targetWindow = StartTargetApp(targetApplication)

            ' Does the automation element exist?
            If targetWindow Is Nothing Then
                Feedback("No target.")
                Return
            End If
            Feedback("Found target.")

            ' Obtain required control patterns from our automation element
            windowPattern = CType( _
            GetControlPattern(targetWindow, windowPattern.Pattern), _
            WindowPattern)

            If (windowPattern Is Nothing) Then Return

            ' Make sure our window is usable.
            ' WaitForInputIdle will return before the specified time 
            ' if the window is ready.
            If (False = windowPattern.WaitForInputIdle(10000)) Then
                Feedback("Object not responding in a timely manner.")
                Return
            End If
            Feedback("Window ready for user interaction")

            ' Register for required events
            RegisterForEvents( _
            targetWindow, windowPattern.Pattern, TreeScope.Element)

            ' find current location of our window
            targetLocation = _
            targetWindow.Current.BoundingRectangle.Location

            ' Obtain required control patterns from our automation element
            transformPattern = CType( _
            GetControlPattern(targetWindow, transformPattern.Pattern), _
            TransformPattern)

            If (transformPattern Is Nothing) Then Return

            ' Is the TransformPattern object moveable?
            If transformPattern.Current.CanMove Then
                ' Enable our WindowMove fields
                xCoordinate.IsEnabled = True
                yCoordinate.IsEnabled = True
                moveTarget.IsEnabled = True

                ' Move element
                transformPattern.Move(0, 0)
            Else
                Feedback("Wndow is not moveable.")
            End If

        Catch exc As ElementNotAvailableException
            Feedback("Client window no longer available.")

        Catch exc As InvalidOperationException
            Feedback("Client window cannot be moved.")
            Return

        Catch exc As Exception
            Feedback(exc.ToString())

        End Try

    End Sub 'OnStartingUp

...

    '' <summary>
    '' Handles the 'Move' button invoked event.
    '' By default, the Move method does not allow an object 
    '' to be moved completely off-screen.
    '' </summary>
    '' <param name="src">The object that raised the event.</param>
    '' <param name="e">Event arguments.</param>
    Private Sub btnMove_Click( _
    ByVal sender As Object, ByVal e As RoutedEventArgs)
        Try
            ' If coordinate left blank, substitute 0
            If (xCoordinate.Text = "") Then xCoordinate.Text = "0"
            If (yCoordinate.Text = "") Then yCoordinate.Text = "0"

            ' Reset background colours
            xCoordinate.Background = System.Windows.Media.Brushes.White
            yCoordinate.Background = System.Windows.Media.Brushes.White

            If (windowPattern.Current.WindowVisualState = WindowVisualState.Minimized) Then
                windowPattern.SetWindowVisualState(WindowVisualState.Normal)
            End If

            Dim X As Double = Double.Parse(xCoordinate.Text)
            Dim Y As Double = Double.Parse(yCoordinate.Text)

            ' Should validate the requested screen location.
            If (X >= (SystemParameters.WorkArea.Width - targetWindow.Current.BoundingRectangle.Width)) Then
                Feedback("X-coordinate would place the window all or partially off-screen.")
                xCoordinate.Background = System.Windows.Media.Brushes.Yellow
            End If

            If (Y >= (SystemParameters.WorkArea.Height - targetWindow.Current.BoundingRectangle.Height)) Then
                Feedback("Y-coordinate would place the window all or partially off-screen.")
                yCoordinate.Background = System.Windows.Media.Brushes.Yellow
            End If

            ' transformPattern was obtained from the target window.
            transformPattern.Move(X, Y)

        Catch exc As ElementNotAvailableException
            Feedback("Client window no longer available.")

        Catch exc As InvalidOperationException
            Feedback("Client window cannot be moved.")
            Return

        Catch exc As Exception
            Feedback(exc.ToString())

        End Try

    End Sub
    /// <summary>
    /// The Startup handler.
    /// </summary>
    /// <param name="e">The event arguments</param>
    protected override void OnStartup(StartupEventArgs e)
    {
        // Start the WindowMove client.
        CreateWindow();

        try
        {
            // Obtain an AutomationElement from the target window handle.
            targetWindow = StartTargetApp(targetApplication);

            // Does the automation element exist?
            if (targetWindow == null)
            {
                Feedback("No target.");
                return;
            }
            Feedback("Found target.");
            
            // find current location of our window
            targetLocation = targetWindow.Current.BoundingRectangle.Location;

            // Obtain required control patterns from our automation element
            windowPattern = GetControlPattern(targetWindow, 
                WindowPattern.Pattern) as WindowPattern;

            if (windowPattern == null) return;

            // Make sure our window is usable.
            // WaitForInputIdle will return before the specified time 
            // if the window is ready.
            if (false == windowPattern.WaitForInputIdle(10000))
            {
                Feedback("Object not responding in a timely manner.");
                return;
            }
            Feedback("Window ready for user interaction");

            // Register for required events
            RegisterForEvents(
                targetWindow, WindowPattern.Pattern, TreeScope.Element);

            // Obtain required control patterns from our automation element
            transformPattern = 
                GetControlPattern(targetWindow, TransformPattern.Pattern) 
                as TransformPattern;

            if (transformPattern == null) return;

            // Is the TransformPattern object moveable?
            if (transformPattern.Current.CanMove)
            {
                // Enable our WindowMove fields
                xCoordinate.IsEnabled = true;
                yCoordinate.IsEnabled = true;
                moveTarget.IsEnabled = true;

                // Move element
                transformPattern.Move(0, 0);
            }
            else
            {
                Feedback("Wndow is not moveable.");
            }
        }
        catch (ElementNotAvailableException)
        {
            Feedback("Client window no longer available.");
            return;
        }
        catch (InvalidOperationException)
        {
            Feedback("Client window cannot be moved.");
            return;
        }
        catch (Exception exc)
        {
            Feedback(exc.ToString());
        }
    }

...

    /// <summary>
    /// Handles the 'Move' button invoked event.
    /// By default, the Move method does not allow an object 
    /// to be moved completely off-screen.
    /// </summary>
    /// <param name="src">The object that raised the event.</param>
    /// <param name="e">Event arguments.</param>
    private void btnMove_Click(object src, RoutedEventArgs e)
    {
        try
        {
            // If coordinate left blank, substitute 0
            if (xCoordinate.Text == "") xCoordinate.Text = "0";
            if (yCoordinate.Text == "") yCoordinate.Text = "0";

            // Reset background colours
            xCoordinate.Background = System.Windows.Media.Brushes.White;
            yCoordinate.Background = System.Windows.Media.Brushes.White;

            if (windowPattern.Current.WindowVisualState ==
                WindowVisualState.Minimized)
                windowPattern.SetWindowVisualState(WindowVisualState.Normal);

            double X = double.Parse(xCoordinate.Text);
            double Y = double.Parse(yCoordinate.Text);

            // Should validate the requested screen location
            if ((X < 0) ||
                (X >= (SystemParameters.WorkArea.Width -
                targetWindow.Current.BoundingRectangle.Width)))
            {
                Feedback("X-coordinate would place the window all or partially off-screen.");
                xCoordinate.Background = System.Windows.Media.Brushes.Yellow;
            }

            if ((Y < 0) ||
                (Y >= (SystemParameters.WorkArea.Height -
                targetWindow.Current.BoundingRectangle.Height)))
            {
                Feedback("Y-coordinate would place the window all or partially off-screen.");
                yCoordinate.Background = System.Windows.Media.Brushes.Yellow;
            }

            // transformPattern was obtained from the target window.
            transformPattern.Move(X, Y);
        }
        catch (ElementNotAvailableException)
        {
            Feedback("Client window no longer available.");
            return;
        }
        catch (InvalidOperationException)
        {
            Feedback("Client window cannot be moved.");
            return;
        }
    }

See Also

Other Resources

WindowPattern Sample