UI オートメーション ツリーを移動する方法
このトピックには、IUIAutomationTreeWalker インターフェイスを使用して、Microsoft UI オートメーション ツリー内の要素を調べる方法を示すコード例が含まれています。 それは、次のトピックを検討します。
要素の子孫を調べる
次のコード例は、UI 要素のすべての子孫を調べ、そのコントロール タイプを階層リストに表示する再帰関数です。
// 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;
}
祖先の要素を調べる
次のコード例は、要素の祖先を調べて親要素を識別する関数です。 これは、コントロールの親ウィンドウを識別する必要がある場合に便利です。 この関数は、最上位の要素 (つまり、親がデスクトップである要素) に対して NULL を返します。
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;
}
関連トピック
-
Conceptual