1

I want to capture 'Send' button event of outlook using UI Automation. Right now i am able to get 'Focus Change Event' like whenever iam minimizing or maximizing the WINWORD window the the event is raised instead of that i want to get the event on Send button click.

  private void SendButtonInvoke()
    {
        Process[] processes = Process.GetProcessesByName("WINWORD");
        AutomationElement aeOutLook = null;
        foreach (var item in processes)
        {
            aeOutLook = AutomationElement.FromHandle(item.MainWindowHandle);
        }
        //AutomationElement outlookelm = AutomationElement.FromHandle(processName.MainWindowHandle);
        AutomationElement buttonAddInstance = aeOutLook.FindFirst(TreeScope.Descendants,
               new PropertyCondition(AutomationElement.NameProperty, "Send"));

        if (buttonAddInstance == null)
        {
            MessageBox.Show("Add button instance not found");
        }
        else
        {

            AutomationPropertyChangedEventHandler ButtonEvent =
                new AutomationPropertyChangedEventHandler(ButtonChecked_EventHandler);
            //Attaching the EventHandler
            Automation.AddAutomationPropertyChangedEventHandler(buttonAddInstance, TreeScope.Children,
                ButtonEvent, AutomationElement.NameProperty);
        }
    }


private void ButtonChecked_EventHandler(object sender, AutomationEventArgs e)
    {
        AutomationElement ar = sender as AutomationElement;
        MessageBox.Show("Button Clicked Sucessfully.");
    }
Muzammil Ansari
  • 143
  • 1
  • 13

2 Answers2

0

You have to specifiy the EventHandler for the involved UIA Pattern. (For your case it's likely to be the InvokePattern):

Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent, AutomationElement buttonAddInstance ,TreeScope.Element, new AutomationEventHandler(OnStartInvoke));

private static void OnStartInvoke(object src, AutomationEventArgs e)
{
    //logic
}
Haphil
  • 1,180
  • 1
  • 14
  • 33
  • do you "invoke" (via Pattern) or directly click on the button via mouse? it could make a difference. – Haphil Oct 19 '15 at 10:55
  • Direct click on the button via mouse. – Muzammil Ansari Oct 19 '15 at 11:46
  • Then it's not possible in your case to stick with pure UI Automation. You will need to use windows mouse hooks. you could try this: http://globalmousekeyhook.codeplex.com/ seems promising. alternativly here are some questions already covering your topic: http://stackoverflow.com/questions/7497024/how-to-detect-mouse-clicks http://stackoverflow.com/questions/3312752/capturing-mouse-keyboard-events-outside-of-form-app-running-in-background hope this helps ;) – Haphil Oct 19 '15 at 13:15
  • Sure. i ll check it out.Thank you – Muzammil Ansari Oct 20 '15 at 04:16
0

I wrote and tested the code below and it seems to work for me.

    private void AddEmailSendEvent()
    {
        // Find the new email window
        PropertyCondition newEmailWindowCondition = new PropertyCondition(AutomationElement.NameProperty, "Untitled - Message (HTML) ");
        AutomationElement NewEmailWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children, newEmailWindowCondition);

        // Find the Send Button
        PropertyCondition sendEmailButtonCondition = new PropertyCondition(AutomationElement.NameProperty, "Send");
        AutomationElement sendButton = NewEmailWindow.FindFirst(TreeScope.Descendants, sendEmailButtonCondition);

        // If supported, add the invoke event
        if (sendButton.GetSupportedPatterns().Any(p => p.Equals(InvokePattern.Pattern)))
            Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent, sendButton, TreeScope.Element, handler);
    }

    private void handler(object sender, AutomationEventArgs e)
    {   
        // Do whatever is needed, for testing this just adds a message to my forms Main UI
        AddMessage("Invoke event occured");
    }

I should note that I'm using the .Net 4.0 automation libs. I've found the older ones don't always work the way I want them. I also tested this with Outlook 2013, and both outlook and the new email message were already open when I tested this. It doesn't handle waiting for them to appear.

Just so your aware, these events don't always work for all controls. Some custom controls are made in such a way the invoke events are not reported to the UI in a way the event can register. With that said, from my testing you should be able to use this method on the send button.

Invoking vs mouse clicks: Just to add a little more detail, the standard control causes the invoke event to fire when a user clicks it. "Invoke" is just the standard event fired on clickable controls. The only time a click wouldn't fire the same invoke is if the developer decided to intercept the click somehow and redirect it elsewhere. I've seen this a lot when people build there own custom controls.

If your not sure about whether a control using/firing the invoke event or not you can get use the Accessible Event Watcher to watch a control as you click it. You can get more information on the tool here: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317979(v=vs.85).aspx

Hack
  • 144
  • 4
  • I have tried this code but on my send button click it is not working. It finds the Send Button and the Outlook Mail window alright but on send button click my handler is not working. Also, Please let me know if there is a way where I can catch the event of a "Dialog Button Click" – Faran Saleem Sep 30 '19 at 11:55