如何使用C#中的UI自动化为Outlook捕获“发送”按钮事件?

时间:2015-10-16 07:20:08

标签: c# c#-4.0 outlook ui-automation microsoft-ui-automation

我想使用UI Automation捕获outlook的“发送”按钮事件。 现在我能够得到'焦点变化事件',就像每当我最小化或最大化WINWORD窗口时,事件被提出而不是我希望在发送按钮点击时获得事件。

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

2 个答案:

答案 0 :(得分:0)

您必须为涉及的UIA模式指定EventHandler。 (对于你的情况,它可能是InvokePattern):

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

private static void OnStartInvoke(object src, AutomationEventArgs e)
{
    //logic
}

答案 1 :(得分:0)

我编写并测试了下面的代码,它似乎对我有用。

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

我应该注意到我正在使用.Net 4.0自动化库。我发现旧版的并不总是按照我想要的方式工作。我还使用Outlook 2013对此进行了测试,当我测试时,Outlook和新电子邮件消息都已打开。它不处理等待它们出现。

您知道,这些事件并不总是适用于所有控件。一些自定义控件以这样的方式生成,调用事件不会以事件可以注册的方式报告给UI。话虽如此,从我的测试中你应该可以在发送按钮上使用这个方法。

调用vs鼠标点击:只是为了添加更多细节,标准控件会在用户单击它时触发调用事件。 “Invoke”只是针对可点击控件触发的标准事件。如果开发人员决定以某种方式拦截点击并将其重定向到其他位置,则单击不会触发相同调用的唯一时间。当人们构建自己的自定义控件时,我已经看到了很多。

如果您不确定控件是否使用/触发调用事件,您可以使用Accessible Event Watcher在您单击它时观察控件。您可以在此处获取有关该工具的更多信息:https://msdn.microsoft.com/en-us/library/windows/desktop/dd317979(v=vs.85).aspx