Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: UI
I cannot perform very simple task using Microsoft UI automation API -> write something in notepad..
 
Process process = Process.GetProcessesByName("notepad").Length == 0
                                  ? Process.Start("notepad")
                                  : Process.GetProcessesByName("notepad")[0];
Condition processIdCondition = new PropertyCondition(AutomationElement.ProcessIdProperty, process.Id);
var window = AutomationElement.RootElement.FindFirst(TreeScope.Children, processIdCondition);
window.SetFocus();
var edit = window.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "15"));
// control type is ControlType.Document
string controlType = ((ControlType)edit.GetCurrentPropertyValue(AutomationElement.ControlTypeProperty)).ProgrammaticName;
// only 2 patterns are supported TextPattern and ScrollPattern
var patterns = edit.GetSupportedPatterns().Select(p => p.ProgrammaticName).ToArray();
// using TextPattern I can get a text
var textPattern = edit.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
string text = textPattern.DocumentRange.GetText(-1);
// but what about setting the value?
// Microsoft says that ValuePattern is not supported
// 
// Does it mean that we have no way to set content of Document type?
 
http://msdn.microsoft.com/en-us/library/ms752058.aspx#Required_UI_Automation_Control_Patterns
 
Any ideas?
Posted 17-Nov-12 21:30pm
TRicK583
Comments
Sergey Alexandrovich Kryukov at 18-Nov-12 12:25pm
   
What is "notepad text"? :-)

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I ended up using SendKeys as the Document object in notepad does not support the "SetValue" ValuePattern.
 
    private void NotepadInsertButton_Click(object sender, EventArgs e)
    {
        string windowTitle = "Untitled - Notepad";
        AutomationElement result = getRootElement(windowTitle);
 
        if (result == null)
        {
            throw new ArgumentException();
        }
        Condition conditions = new AndCondition(
          new PropertyCondition(AutomationElement.IsEnabledProperty, true),
          new PropertyCondition(AutomationElement.ControlTypeProperty,
          ControlType.Document)
          );
 
        // Find all children that match the specified conditions.
        AutomationElementCollection elementCollection =
           result.FindAll(TreeScope.Children, conditions);
        //return elementCollection;

        foreach (AutomationElement x in elementCollection)
        {
            InsertTextUsingUIAutomation(x, "Hello World!");
        }
    }
 
    private AutomationElement getRootElement(string windowTitle)
    {
        AutomationElement root = AutomationElement.RootElement;
        AutomationElement result = null;
        foreach (AutomationElement window in root.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window)))
        {
            try
            {
                if (window.Current.Name.Contains(windowTitle) && window.Current.IsKeyboardFocusable)
                {
                    result = window;
                    break;
                }
            }
            catch (Exception e)
            {
                //this will throw if a window has been closed since the start of the program.. no need to stop
            }
        }
 
        return result;
    }
 
        
        Condition conditions = new AndCondition(
          new PropertyCondition(AutomationElement.IsEnabledProperty, true),
          new PropertyCondition(AutomationElement.ControlTypeProperty,
              ControlType.Document)
          );
 
        // Find all children that match the specified conditions.
        AutomationElementCollection elementCollection =
            result.FindAll(TreeScope.Children, conditions);
        //return elementCollection;

        foreach (AutomationElement x in elementCollection)
        {
            InsertTextUsingUIAutomation(x, "Hello World!");
        }
 
///--------------------------------------------------------------------
        /// <summary>
        /// Inserts a string into each text control of interest.
        /// </summary>
        /// <param name="element">A text control.</param>
        /// <param name="value">The string to be inserted.</param>
        ///--------------------------------------------------------------------
        private void InsertTextUsingUIAutomation(AutomationElement element, string value)
        {
            try
            {
                // Validate arguments / initial setup
                if (value == null)
                    throw new ArgumentNullException(
                        "String parameter must not be null.");
 
                if (element == null)
                    throw new ArgumentNullException(
                        "AutomationElement parameter must not be null");
 
                // A series of basic checks prior to attempting an insertion.
                //
                // Check #1: Is control enabled?
                // An alternative to testing for static or read-only controls
                // is to filter using
                // PropertyCondition(AutomationElement.IsEnabledProperty, true)
                // and exclude all read-only text controls from the collection.
                if (!element.Current.IsEnabled)
                {
                    throw new InvalidOperationException(
                        "The control with an AutomationID of "
                        + element.Current.AutomationId.ToString()
                        + " is not enabled.\n\n");
                }
 
                // Check #2: Are there styles that prohibit us
                //           from sending text to this control?
                if (!element.Current.IsKeyboardFocusable)
                {
                    throw new InvalidOperationException(
                        "The control with an AutomationID of "
                        + element.Current.AutomationId.ToString()
                        + "is read-only.\n\n");
                }
 

                // Once you have an instance of an AutomationElement,
                // check if it supports the ValuePattern pattern.
                object valuePattern = null;
 
                // Control does not support the ValuePattern pattern
                // so use keyboard input to insert content.
                //
                // NOTE: Elements that support TextPattern
                //       do not support ValuePattern and TextPattern
                //       does not support setting the text of
                //       multi-line edit or document controls.
                //       For this reason, text input must be simulated
                //       using one of the following methods.
                //
                if (!element.TryGetCurrentPattern(
                    ValuePattern.Pattern, out valuePattern))
                {
                    richTextBox1.AppendText("The control with an AutomationID of ");
                    richTextBox1.AppendText(element.Current.AutomationId.ToString());
                    richTextBox1.AppendText(" does not support ValuePattern.");
                    richTextBox1.AppendText(" Using keyboard input.\n");
 
                    // Set focus for input functionality and begin.
                    element.SetFocus();
 
                    // Pause before sending keyboard input.
                    Thread.Sleep(100);
 
                    // Delete existing content in the control and insert new content.
                    SendKeys.SendWait("^{HOME}");   // Move to start of control
                    SendKeys.SendWait("^+{END}");   // Select everything
                    SendKeys.SendWait("{DEL}");     // Delete selection
                    SendKeys.SendWait(value);
                }
                // Control supports the ValuePattern pattern so we can
                // use the SetValue method to insert content.
                else
                {
                    //string currVal = ((ValuePattern)valuePattern).Current.Value.ToString();
                    richTextBox1.AppendText("The control with an AutomationID of ");
                    richTextBox1.AppendText(element.Current.AutomationId.ToString());
                    richTextBox1.AppendText((" supports ValuePattern."));
                    richTextBox1.AppendText(" Using ValuePattern.SetValue().\n");
 
                    // Set focus for input functionality and begin.
                    element.SetFocus();
 
                    ((ValuePattern)valuePattern).SetValue(value);
 
                }
            }
            catch (ArgumentNullException exc)
            {
                richTextBox1.AppendText(exc.Message);
            }
            catch (InvalidOperationException exc)
            {
                richTextBox1.AppendText(exc.Message);
            }
            finally
            {
                richTextBox1.AppendText("");
            }
        }
  Permalink  
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 480
1 Maciej Los 304
2 Richard MacCutchan 225
3 BillWoodruff 169
4 Suraj Sahoo | Coding Passion 155
0 OriginalGriff 8,759
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,639
3 Maciej Los 5,269
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web04 | 2.8.1411028.1 | Last Updated 26 Nov 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100