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?