Updated Synthuse to list WPF and Silverlight Windows

The WpfBridge native library can now enumerate all WPF and Silverlight
Windows and list them in Synthuse.  Still need to add a method to
connect the Drag Target to locate the WPF window.
This commit is contained in:
Edward Jakubowski
2014-04-05 17:24:08 -04:00
parent d92f85e1b8
commit 1809e2ad55
14 changed files with 297 additions and 79 deletions

View File

@@ -34,6 +34,8 @@ array<System::Int32> ^ WpfAutomation::convertRuntimeIdString(System::String ^run
AutomationElement ^ WpfAutomation::findAutomationElementById(System::String ^runtimeIdValue)
{
if (runtimeIdValue == nullptr || runtimeIdValue->Equals(L""))
return AutomationElement::RootElement;
array<System::Int32> ^idArray = this->convertRuntimeIdString(runtimeIdValue);
Condition ^pcFramework = gcnew PropertyCondition(AutomationElement::FrameworkIdProperty, this->frameworkId);
Condition ^pcRunId = gcnew PropertyCondition(AutomationElement::RuntimeIdProperty, idArray);
@@ -47,22 +49,28 @@ array<System::String ^> ^ WpfAutomation::getRuntimeIdsFromCollection(System::Win
System::Int32 count = 0;
for each(AutomationElement ^child in collection)
{
System::Object ^currentVal = child->GetCurrentPropertyValue(AutomationElement::RuntimeIdProperty);
if (currentVal != nullptr)
{
array<System::Int32> ^idArray = (array<System::Int32> ^)currentVal;
for each(System::Int32 val in idArray)
{
idStrArray[count] += System::Convert::ToString(val) + L"-";
//System::String->Concat(idStrArray[count], System::String->Concat(val->ToString(), L"-"));
}
idStrArray[count] = idStrArray[count]->TrimEnd('-');
//System::Console::WriteLine("id: {0}", idStrArray[count]);
}
idStrArray[count] = getRuntimeIdFromElement(child);
++count;
}
return idStrArray;
}
System::String ^ WpfAutomation::getRuntimeIdFromElement(System::Windows::Automation::AutomationElement ^element)
{
System::String ^result = L"";
System::Object ^currentVal = element->GetCurrentPropertyValue(AutomationElement::RuntimeIdProperty);
if (currentVal != nullptr)
{
array<System::Int32> ^idArray = (array<System::Int32> ^)currentVal;
for each(System::Int32 val in idArray)
{
result += System::Convert::ToString(val) + L"-";
}
result = result->TrimEnd('-');
//System::Console::WriteLine("id: {0}", result);
}
return result;
}
//Descendants will walk the full tree of windows, NOT just one level of children
System::Int32 WpfAutomation::countDescendantWindows()
@@ -135,6 +143,84 @@ array<System::String ^> ^ WpfAutomation::EnumDescendantWindowIdsFromHandle(Syste
return getRuntimeIdsFromCollection(aec);
}
array<System::String ^> ^ WpfAutomation::EnumDescendantWindowInfo(System::String ^runtimeIdValue, System::String ^properties)
{
AutomationElement ^parent = findAutomationElementById(runtimeIdValue);
AutomationElementCollection ^aec = parent->FindAll(TreeScope::Descendants, gcnew PropertyCondition(AutomationElement::FrameworkIdProperty, this->frameworkId));
//create array for keeping order of properties
System::String ^delim = L",";
array<System::String ^> ^propSpltArray = properties->Split(delim->ToCharArray());
TreeWalker ^tw = TreeWalker::ControlViewWalker;
array<System::String ^> ^winInfoList = gcnew array<System::String ^>(aec->Count);
System::Int32 count = 0;
for each(AutomationElement ^child in aec) //loop through all descendants
{
array<AutomationProperty^> ^aps = child->GetSupportedProperties();
array<System::String ^> ^propValues = gcnew array<System::String ^>(propSpltArray->Length);//keep order
for(int i=0 ; i < propValues->Length ; i++)
{
propValues[i] = L"";
if (propSpltArray[i]->Equals("ParentRuntimeIdProperty"))//custom property for getting parent
{
propValues[i] = getRuntimeIdFromElement(tw->GetParent(child));
}
}
for each(AutomationProperty ^ap in aps) //loop through all supported Properties for a child
{
System::String ^currentPropertyStr = L""; //current property values
//System::Console::WriteLine("property: {0}", ap->ProgrammaticName);
System::String ^shortPropName = L" null ";
if (ap->ProgrammaticName->Contains(L"."))
shortPropName = ap->ProgrammaticName->Substring(ap->ProgrammaticName->IndexOf(L".") + 1);
if (properties->Contains(shortPropName) || properties->Contains(ap->ProgrammaticName) || ap->ProgrammaticName->Equals(properties))
{
//System::Console::WriteLine("shortPropName: {0}", shortPropName);
System::Object ^currentVal = child->GetCurrentPropertyValue(ap);
if (currentVal == nullptr)
continue;
if (ap->ProgrammaticName->Equals(L"AutomationElementIdentifiers.RuntimeIdProperty"))
{
array<System::Int32> ^idArray = (array<System::Int32> ^)currentVal;
for each(System::Int32 val in idArray)
{
currentPropertyStr += System::Convert::ToString(val) + L"-";
}
currentPropertyStr = currentPropertyStr->TrimEnd('-');
//System::Console::WriteLine("id: {0}", result);
}
else//not runtimeId which is an Int32[]
{
currentPropertyStr = currentVal->ToString();
}
}
if (currentPropertyStr->Equals(L"")) //if there isn't a value skip
continue;
//System::Console::WriteLine("currentPropertyStr: {0}", currentPropertyStr);
//find the correct order to return this property
for(int i=0 ; i < propSpltArray->Length ; i++)
{
if (propSpltArray[i]->Equals(shortPropName) || propSpltArray[i]->Equals(ap->ProgrammaticName))
propValues[i] = currentPropertyStr;
}
}
//output properties in the correct order
for(int i=0 ; i < propSpltArray->Length ; i++)
winInfoList[count] += propValues[i] + L",";
++count;
}
return winInfoList;
}
System::String ^ WpfAutomation::getParentRuntimeId(System::String ^runtimeIdValue)
{
AutomationElement ^target = findAutomationElementById(runtimeIdValue);
TreeWalker ^tw = TreeWalker::ControlViewWalker;
AutomationElement ^parent = tw->GetParent(target);
return getRuntimeIdFromElement(parent);
}
System::String ^ WpfAutomation::getProperty(System::String ^propertyName, System::String ^runtimeIdValue)
{
AutomationElement ^parent = findAutomationElementById(runtimeIdValue);