Cómo recorrer el árbol de Automatización de la interfaz de usuario
Este tema contiene código de ejemplo que muestra cómo usar la interfaz IUIAutomationTreeWalker para recorrer y examinar los elementos del árbol de microsoft Automatización de la interfaz de usuario. Se describen los temas siguientes:
Recorrer descendientes de un elemento
El ejemplo de código siguiente es una función recursiva que recorre todos los descendientes de un elemento de interfaz de usuario y muestra sus tipos de control en una lista jerárquica.
// CAUTION: Do not pass in the root (desktop) element. Traversing the entire subtree
// of the desktop could take a very long time and even lead to a stack overflow.
void ListDescendants(IUIAutomationElement* pParent, int indent)
{
if (pParent == NULL)
return;
IUIAutomationTreeWalker* pControlWalker = NULL;
IUIAutomationElement* pNode = NULL;
g_pAutomation->get_ControlViewWalker(&pControlWalker);
if (pControlWalker == NULL)
goto cleanup;
pControlWalker->GetFirstChildElement(pParent, &pNode);
if (pNode == NULL)
goto cleanup;
while (pNode)
{
BSTR desc;
pNode->get_CurrentLocalizedControlType(&desc);
for (int x = 0; x <= indent; x++)
{
std::wcout << L" ";
}
std::wcout << desc << L"\n";
SysFreeString(desc);
ListDescendants(pNode, indent+1);
IUIAutomationElement* pNext;
pControlWalker->GetNextSiblingElement(pNode, &pNext);
pNode->Release();
pNode = pNext;
}
cleanup:
if (pControlWalker != NULL)
pControlWalker->Release();
if (pNode != NULL)
pNode->Release();
return;
}
Recorrer elementos antecesores
El ejemplo de código siguiente es una función que recorre los antecesores de un elemento para identificar el elemento primario. Esto resulta útil cuando necesita identificar la ventana primaria de un control. La función devuelve NULL para los elementos de nivel superior; es decir, los elementos cuyo elemento primario es el escritorio.
IUIAutomationElement* GetContainingWindow(IUIAutomationElement* pChild)
{
if (pChild == NULL)
return NULL;
IUIAutomationElement* pDesktop = NULL;
HRESULT hr = g_pAutomation->GetRootElement(&pDesktop);
if (FAILED(hr))
return NULL;
BOOL same;
g_pAutomation->CompareElements(pChild, pDesktop, &same);
if (same)
{
pDesktop->Release();
return NULL; // No parent, so return NULL.
}
IUIAutomationElement* pParent = NULL;
IUIAutomationElement* pNode = pChild;
// Create the treewalker.
IUIAutomationTreeWalker* pWalker = NULL;
g_pAutomation->get_ControlViewWalker(&pWalker);
if (pWalker == NULL)
goto cleanup;
// Walk up the tree.
while (TRUE)
{
hr = pWalker->GetParentElement(pNode, &pParent);
if (FAILED(hr) || pParent == NULL)
{
break;
}
g_pAutomation->CompareElements(pParent, pDesktop, &same);
if (same)
{
pDesktop->Release();
pParent->Release();
pWalker->Release();
// Reached desktop, so return next element below it.
return pNode;
}
if (pNode != pChild) // Do not release the in-param.
pNode->Release();
pNode = pParent;
}
cleanup:
if ((pNode != NULL) && (pNode != pChild))
pNode->Release();
if (pDesktop != NULL)
pDesktop->Release();
if (pWalker != NULL)
pWalker->Release();
if (pParent != NULL)
pParent->Release();
return NULL;
}
Temas relacionados
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de