UI Automation events not getting caught from Power

2019-07-20 00:13发布

问题:

I am trying to capture UI Automation events from PowerPoint 2007 (or ideally any version) when the user selects a new Ribbon tab. Using the SDK tools Inspect and AccEvent I have determined that a reasonable "parent" element to catch these events is the "Ribbon Tabs" element.

When I Scope AccEvent to that element, and register for SelectionItem_ElementSelected within the automation events, I get the events as I would expect - when a tab is clicked, AccEvent catches and logs it.

I am only allowed to post two links and can't inline images yet so I have made some mosaics to try and squeeze as much relevant info into each link as possible, here is the link relating to the above mentioned behavior:

http://hirstius.com/media/stackoverflow/UIA_sdk_tools.png

Based upon that, I came up with the following code to catch these events from my program:

// Prior code gets foreground window, determines if it's PPT, and gets a handle to it
currentApp = AutomationElement.FromHandle(foregroundWindow);

// Create condition to find the "Ribbon Tabs" element
Condition propCondition = new PropertyCondition(
  AutomationElement.NameProperty, "Ribbon Tabs",
  PropertyConditionFlags.IgnoreCase);

// Subscribe to events on the "Ribbon Tabs" Element
SubscribeToEvents(currentApp.FindFirst(TreeScope.Descendants, propCondition));

public void SubscribeToEvents(AutomationElement element)
{
  if (element != null)
  {
    Console.WriteLine("Subscribing to PowerPoint UIA Events on object {0} ({1})",
      elementItem.GetCurrentPropertyValue(AutomationElement.NameProperty),
      elementItem.GetCurrentPropertyValue(AutomationElement.AutomationIdProperty));
    UIAeventHandler = new AutomationEventHandler(OnUIAutomationEvent);

    // Subscribe to SelectionItemPattern.ElementSelectedEvent based off AccEvent
    Automation.AddAutomationEventHandler(
      SelectionItemPattern.ElementSelectedEvent,
      element,
      TreeScope.Descendants,
      UIAeventHandler);

    Console.WriteLine("Subscribed to PowerPoint UIA Events");
  }
}

private void OnUIAutomationEvent(object src, AutomationEventArgs e)
{
  // Make sure the element still exists
  AutomationElement sourceElement;
  try
  {
    sourceElement = src as AutomationElement;
  }
  catch (ElementNotAvailableException)
  {
    return;
  }
  Console.WriteLine("UIA Event ( {0} ) for item: {1}",
    e.EventId.ProgrammaticName,
    sourceElement.GetCurrentPropertyValue(AutomationElement.NameProperty));
}

This code results in, well, nothing.

If I subscribe to the top level "Window", still nothing.

If I instead just subscribe to the top level automation element, I DO get the expected events - but with a catch. In AccEvent, the events only appear when the tabs are clicked, truly "selected". When I bind to the Root AutomationElement, I get the events on mouseover/hover and nothing on click. I need the events to come only when the tab is actually selected (which is exactly the behavior AccEvent presents when Scoped to the "Ribbon Tabs" Element).

Results link: http://hirstius.com/media/stackoverflow/UIA_Result.png

I need a way to notify my .NET application when the user selects a new tab on the ribbon, am I missing something obvious?