C# Automation Click Button On Windows 10 Calculator

2k Views Asked by At

So I am new to C# and I would like to make an automation that will click few buttons on Win10 Calculator I downloaded LeanRunner Designer and used it's Model Manager to get Calculator button properties of number 5 and I got:

Auto.getWindow({
  "className": "ApplicationFrameWindow",
  "title": "Calculator"
}).getWindow({
  "className": "Windows.UI.Core.CoreWindow",
  "title": "Calculator"
}).getGeneric({
  "type": "Group",
  "automationId": "NumberPad",
  "name": "Number pad",
  "className": "NamedContainerAutomationPeer"
}).getButton({
  "automationId": "num5Button",
  "name": "Five",
  "className": "Button"
}).click(52, 24);

I transferred getWindow like this and that works

int hwnd=0;
IntPtr hwndChild=IntPtr.Zero;
IntPtr hwndChild2 = IntPtr.Zero;

//Get a handle for the Calculator Application main window
hwnd = FindWindow("ApplicationFrameWindow", "Calculator");
hwndChild = FindWindowEx((IntPtr)hwnd,IntPtr.Zero, "Windows.UI.Core.CoreWindow", "Calculator");             

But now I need to click the button and I'm stuck. I know the end result for click is

SendMessage((int)hwndChild2, BM_CLICK, 0, IntPtr.Zero);

But I'm missing the part to get to the button position. I don't want to use SendKeys. Thank you and sorry if I missed something or made it unclear.

1

There are 1 best solutions below

0
himynameissergey On

As suggested above, this can be done with UIAutomation. For example like this:

public static AutomationElement calcUI;

public void FindAndClickButton(string name)
{
    System.Windows.Automation.Condition condition1 = new PropertyCondition(AutomationElement.ClassNameProperty, "Button");
    System.Windows.Automation.Condition condition2 = new PropertyCondition(AutomationElement.NameProperty, name);
    System.Windows.Automation.Condition condition = new AndCondition(condition1, condition2);
    AutomationElement button = calcUI.FindFirst(TreeScope.Descendants, condition);
    InvokePattern btnPattern = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
    btnPattern.Invoke();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
    var calc = System.Diagnostics.Process.Start("calc");
    //wait for the UI to appear
    calc.WaitForInputIdle(5000);
    System.Threading.Thread.Sleep(2000);

    AutomationElement root = AutomationElement.RootElement;
    System.Windows.Automation.Condition condition = new PropertyCondition(AutomationElement.NameProperty, "Calculator");

    calcUI = root.FindFirst(TreeScope.Children, condition);
    if (calcUI != null)
    {
        // get and click the buttons for the calculation
        FindAndClickButton("Five");
        FindAndClickButton("Plus");
        FindAndClickButton("Nine");
        FindAndClickButton("Multiply by");
        FindAndClickButton("Three");
        FindAndClickButton("Divide by");
        FindAndClickButton("Four");
        FindAndClickButton("Equals");
        //get the result
        System.Windows.Automation.Condition conditionResult = new PropertyCondition(AutomationElement.AutomationIdProperty, "CalculatorResults");
        var result = calcUI.FindFirst(TreeScope.Descendants, conditionResult);
        MessageBox.Show(result.Current.Name);
    }
}

Don't forget to add references to the project

UIAutomationClient
UIAutomationTypes