I'm currently adding UIA support to a pane control and child control by implementing IRawElementProviderFragmentRoot
and IRawElementProviderFragment
respectively.
UIA fragments use the method public object GetPropertyValue(int propertyId)
to return a specific property to a test recorder such as Ranorex or Test Complete. For example:
/// <summary>
/// Retrieves the value of a property supported by the UI Automation provider.
/// </summary>
/// <param name="propertyId"></param>
/// <returns></returns>
public object GetPropertyValue(int propertyId)
{
if (propertyId == AutomationElementIdentifiers.NameProperty.Id)
{
// Name of this control. Since this is a top level pane, we'll use the partition name
return View.Document.FullName;
}
else if (propertyId == AutomationElementIdentifiers.ControlTypeProperty.Id)
{
// Pane controls represent a level of grouping lower than windows or documents, but above individual controls.
// The user can navigate between panes and within contents of the current pane, but cannot navigate between items in
// different panes. The pane navigation shortcut is typically CTRL + TAB.
return ControlType.Pane.Id;
}
else if (propertyId == AutomationElementIdentifiers.IsContentElementProperty.Id)
{
// Indicates whether the element contains content that is valuable to the end user
return true;
}
else if (propertyId == AutomationElementIdentifiers.IsControlElementProperty.Id)
{
// Indicates whether the element is viewed as a control
return true;
}
else if (propertyId == AutomationElementIdentifiers.IsKeyboardFocusableProperty.Id)
{
// You can't explicitly focus a tab, the whole window gets focused
return false;
}
else
{
// Null indicates no support
return null;
}
}
I wish to register a custom property and handle the Get call in the method above. According to this MSDN article, your custom property can return
- UIAutomationType_Bool
- UIAutomationType_Double
- UIAutomationType_Element
- UIAutomationType_Int
- UIAutomationType_Point
- UIAutomationType_String
which is exactly what I want. Unfortunately, the instructions are in C++ and there doesn't seem to be a corresponding C# assembly to do all this. Will I have to do some managed->unmanaged marshaling to achieve this? How would I go about it?
Thanks in advance!