I have the handle of a window and what I want to do is click it's button named "Load Settings". I have 2 problems.
- My first problem is when I call Invoke on a certain InvokePattern, it brings the window to focus and this is undesirable for my application.
My second problem is visible and documented in the comments towards the end of my following code:
AutomationElement aeBot = AutomationElement.FromHandle(mbotSettingList.ElementAt(i).getWindowHandle()); AutomationElement aeButtonLoadSettings = aeBot.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Load Settings")); InvokePattern ipClickLoadSettings = (InvokePattern)aeButtonLoadSettings.GetCurrentPattern(InvokePattern.Pattern); Thread invokeLoadSettingsThread = new Thread(ipClickLoadSettings.Invoke); InvokePattern ipClickOpen = null; AutomationElement aeOpenDialogEdit = null; AutomationElement aeButtonOpen = null; AutomationElementCollection aeDialogs = null; AutomationElement aeOpenDialog = null; ValuePattern vpOpenDialogEdit = null; //Using a thread to invoke the Load Settings button click because as a result of clicking Load Settings a dialog is opened and invoke doesnt return for nealy 10 seconds invokeLoadSettingsThread.Start(); //We probably wont join() this thread because it goes on for far longer than we expect to be in this function //Get a collection of the Dialog windows that are direct children of the main window we have a handle to aeDialogs = aeBot.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "#32770")); while (aeDialogs.Count == 0) { //This while loop is to continue to check for the Open file dialog as it may take a little time to open aeDialogs = aeBot.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "#32770")); Thread.Sleep(250); } for (int j = 0; j < aeDialogs.Count; j++) { //There is usually only 1 child dialog window, but just make sure we have the correct one if (aeDialogs[j].Current.Name == "Open") { Debug.WriteLine("Found open dialog!"); aeOpenDialog = aeDialogs[j]; break; } } //Inside the Open window, the first Edit window is the one where the file name/path should be entered aeOpenDialogEdit = aeOpenDialog.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ClassNameProperty, "Edit")); //Set the value of the file name/path to the string variable "loadSettingsString" vpOpenDialogEdit = (ValuePattern)aeOpenDialogEdit.GetCurrentPattern(ValuePattern.Pattern); vpOpenDialogEdit.SetValue(loadSettingsString); //******************************************PROBLEM BEGINING BELOW****************************************** //Using multiple methods, we can successfully get a successful AutomationElement for the "Open" button in the Open file dialog aeButtonOpen = aeOpenDialog.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, "Open")); //aeButtonOpen = aeOpenDialog.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, "Cancel")); //Something to consider: If we assigned aeButtonOpen to the AutomationElement we find be looking for "Cancel" rather than "Open" Debug.WriteLine(aeButtonOpen.Current.Name + " button found!"); //Prints "Open button found!" //If aeButtonOpen were assigned to "Cancel", this would print "Cancel button found!" ipClickOpen = (InvokePattern)aeButtonOpen.GetCurrentPattern(InvokePattern.Pattern); //GetCurrentPattern has returned null //If aeButtonOpen were assigned to "Cancel", this would NOT be null ipClickOpen.Invoke(); //Invoke() on a null results in "Unsupported Pattern" exception //If aeButtonOpen were assigned to "Cancel", this would work and the Open file dialog would then be exited just as if cancel were clicked