How to Capture 'Send' button event for Out

2019-08-15 15:27发布

问题:

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.");
    }

回答1:

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
}


回答2:

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