C++ 使用uiautomation和c+;在windows上获取子窗口按钮的标题+;
我想在windows上使用uiautomation with C++获取此缩放会议的“静音我的音频”标题。 这是我当前的呼叫代码:C++ 使用uiautomation和c+;在windows上获取子窗口按钮的标题+;,c++,windows,winapi,ui-automation,microsoft-ui-automation,C++,Windows,Winapi,Ui Automation,Microsoft Ui Automation,我想在windows上使用uiautomation with C++获取此缩放会议的“静音我的音频”标题。 这是我当前的呼叫代码: // Get the handle of the Zoom Meetings window. zoomWnd = ::FindWindow(NULL, "Zoom Meeting"); if (zoomWnd != NULL) { std::cout<<"zoom meeting"<&l
// Get the handle of the Zoom Meetings window.
zoomWnd = ::FindWindow(NULL, "Zoom Meeting");
if (zoomWnd != NULL)
{
std::cout<<"zoom meeting"<<"\n";
IUIAutomationElement *zoom = GetTopLevelWindowByName(L"Zoom Meeting");
rawListDescendants(zoom, "Meeting");
}
GetToLevel WindowByName函数定义:
IUIAutomationElement *GetTopLevelWindowByName(LPWSTR windowName)
{
if (windowName == NULL)
{
return NULL;
}
VARIANT varProp;
varProp.vt = VT_BSTR;
varProp.bstrVal = SysAllocString(windowName);
if (varProp.bstrVal == NULL)
{
return NULL;
}
IUIAutomationElement *pRoot = NULL;
IUIAutomationElement *pFound = NULL;
// Get the desktop element.
HRESULT hr = g_pAutomation->GetRootElement(&pRoot);
if (FAILED(hr) || pRoot == NULL)
{
goto cleanup;
}
// Get a top-level element by name, such as "Program Manager"
IUIAutomationCondition *pCondition = NULL;
hr = g_pAutomation->CreatePropertyCondition(UIA_NamePropertyId, varProp, &pCondition);
if (FAILED(hr))
{
goto cleanup;
}
pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);
cleanup:
if (pRoot != NULL)
pRoot->Release();
if (pCondition != NULL)
pCondition->Release();
VariantClear(&varProp);
return pFound;
}
void rawListDescendants(IUIAutomationElement *pParent, std::string windowType)
{
if (pParent == NULL)
return;
IUIAutomationTreeWalker *pControlWalker = NULL;
IUIAutomationElement *pNode = NULL;
g_pAutomation->get_RawViewWalker(&pControlWalker);
if (pControlWalker == NULL)
{
goto cleanup;
}
pControlWalker->GetFirstChildElement(pParent, &pNode);
if (pNode == NULL)
{
goto cleanup;
}
while (pNode)
{
BSTR desc;
BSTR sName;
pNode->get_CurrentLocalizedControlType(&desc);
pNode->get_CurrentName(&sName);
std::wcout<<"sName: "<<sName<<"\n";
//std::wcout<<"desc: "<<desc<<"\n";
// only go into windows and panes
if (desc != NULL)
if (0 == wcscmp(desc, L"window") || 0 == wcscmp(desc, L"pane"))
rawListDescendants(pNode, windowType);
if (desc != NULL)
SysFreeString(desc);
if (sName != NULL)
SysFreeString(sName);
// get the next element
IUIAutomationElement *pNext;
pControlWalker->GetNextSiblingElement(pNode, &pNext);
pNode->Release();
pNode = pNext;
}
cleanup:
if (pControlWalker != NULL)
pControlWalker->Release();
if (pNode != NULL)
pNode->Release();
return;
}
函数定义:
IUIAutomationElement *GetTopLevelWindowByName(LPWSTR windowName)
{
if (windowName == NULL)
{
return NULL;
}
VARIANT varProp;
varProp.vt = VT_BSTR;
varProp.bstrVal = SysAllocString(windowName);
if (varProp.bstrVal == NULL)
{
return NULL;
}
IUIAutomationElement *pRoot = NULL;
IUIAutomationElement *pFound = NULL;
// Get the desktop element.
HRESULT hr = g_pAutomation->GetRootElement(&pRoot);
if (FAILED(hr) || pRoot == NULL)
{
goto cleanup;
}
// Get a top-level element by name, such as "Program Manager"
IUIAutomationCondition *pCondition = NULL;
hr = g_pAutomation->CreatePropertyCondition(UIA_NamePropertyId, varProp, &pCondition);
if (FAILED(hr))
{
goto cleanup;
}
pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);
cleanup:
if (pRoot != NULL)
pRoot->Release();
if (pCondition != NULL)
pCondition->Release();
VariantClear(&varProp);
return pFound;
}
void rawListDescendants(IUIAutomationElement *pParent, std::string windowType)
{
if (pParent == NULL)
return;
IUIAutomationTreeWalker *pControlWalker = NULL;
IUIAutomationElement *pNode = NULL;
g_pAutomation->get_RawViewWalker(&pControlWalker);
if (pControlWalker == NULL)
{
goto cleanup;
}
pControlWalker->GetFirstChildElement(pParent, &pNode);
if (pNode == NULL)
{
goto cleanup;
}
while (pNode)
{
BSTR desc;
BSTR sName;
pNode->get_CurrentLocalizedControlType(&desc);
pNode->get_CurrentName(&sName);
std::wcout<<"sName: "<<sName<<"\n";
//std::wcout<<"desc: "<<desc<<"\n";
// only go into windows and panes
if (desc != NULL)
if (0 == wcscmp(desc, L"window") || 0 == wcscmp(desc, L"pane"))
rawListDescendants(pNode, windowType);
if (desc != NULL)
SysFreeString(desc);
if (sName != NULL)
SysFreeString(sName);
// get the next element
IUIAutomationElement *pNext;
pControlWalker->GetNextSiblingElement(pNode, &pNext);
pNode->Release();
pNode = pNext;
}
cleanup:
if (pControlWalker != NULL)
pControlWalker->Release();
if (pNode != NULL)
pNode->Release();
return;
}
void rawlist子体(IUIAutomationeElement*pParent,std::string windowType)
{
如果(pParent==NULL)
返回;
IUIAutomationTreeWalker*pControlWalker=NULL;
IUIAutomationeElement*pNode=NULL;
g_pAutomation->get_RawViewWalker(&pControlWalker);
if(pControlWalker==NULL)
{
去清理;
}
pControlWalker->GetFirstChildElement(pParent和pNode);
if(pNode==NULL)
{
去清理;
}
while(pNode)
{
BSTR描述;
BSTR sName;
pNode->get_CurrentLocalizedControlType(&desc);
pNode->get_CurrentName(&sName);
std::wcout一种解决方案是,您可以使用找到所有按钮,然后将名称与“静音我的音频”进行比较
下面是一个您可以参考的示例(我假设您确实拥有按钮的父窗口句柄:hwnd
):
FindControl功能:
void FindControl(const long controlType, BSTR controlName)
{
HRESULT hr;
BSTR name;
IUIAutomationCondition *pCondition;
VARIANT varProp;
varProp.vt = VT_I4;
varProp.uintVal = controlType;
hr = pClientUIA->CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, &pCondition);
IUIAutomationElementArray *pElementFound;
hr = pRootElement->FindAll(TreeScope_Subtree, pCondition, &pElementFound);
int eleCount;
pElementFound->get_Length(&eleCount);
if (eleCount == 0)
return;
for (int i = 0; i <= eleCount; i++)
{
IUIAutomationElement *pElement;
hr = pElementFound->GetElement(i, &pElement);
hr = pElement->get_CurrentName(&name);
wprintf(L"Control Name: %s\n", name);
if (!lstrcmp(controlName, name))
{
printf("Found it!\n");
}
}
}
void FindControl(const long controlType,BSTR controlName)
{
HRESULT-hr;
BSTR名称;
IUIAutomationCondition*pccondition;
变异varProp;
varProp.vt=vt_I4;
varProp.uintVal=控制类型;
hr=pClientUIA->CreatePropertyCondition(UIA\u ControlTypePropertyId、varProp和pcCondition);
IUIAutomationElementArray*pElementFound;
hr=prootement->FindAll(树范围子树、pCondition和pElementFound);
整数计数;
pElementFound->获取长度(&eleCount);
if(eleCount==0)
返回;
for(int i=0;i GetElement(i,&pElement);
hr=pElement->get_CurrentName(&name);
wprintf(L“控件名称:%s\n”,名称);
如果(!lstrcmp(controlName,name))
{
printf(“找到了!\n”);
}
}
}
一种解决方案是,您可以使用找到所有按钮,然后将名称与“静音我的音频”进行比较
下面是一个您可以参考的示例(我假设您确实拥有按钮的父窗口句柄:hwnd
):
FindControl功能:
void FindControl(const long controlType, BSTR controlName)
{
HRESULT hr;
BSTR name;
IUIAutomationCondition *pCondition;
VARIANT varProp;
varProp.vt = VT_I4;
varProp.uintVal = controlType;
hr = pClientUIA->CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, &pCondition);
IUIAutomationElementArray *pElementFound;
hr = pRootElement->FindAll(TreeScope_Subtree, pCondition, &pElementFound);
int eleCount;
pElementFound->get_Length(&eleCount);
if (eleCount == 0)
return;
for (int i = 0; i <= eleCount; i++)
{
IUIAutomationElement *pElement;
hr = pElementFound->GetElement(i, &pElement);
hr = pElement->get_CurrentName(&name);
wprintf(L"Control Name: %s\n", name);
if (!lstrcmp(controlName, name))
{
printf("Found it!\n");
}
}
}
void FindControl(const long controlType,BSTR controlName)
{
HRESULT-hr;
BSTR名称;
IUIAutomationCondition*pccondition;
变异varProp;
varProp.vt=vt_I4;
varProp.uintVal=控制类型;
hr=pClientUIA->CreatePropertyCondition(UIA\u ControlTypePropertyId、varProp和pcCondition);
IUIAutomationElementArray*pElementFound;
hr=prootement->FindAll(树范围子树、pCondition和pElementFound);
整数计数;
pElementFound->获取长度(&eleCount);
if(eleCount==0)
返回;
for(int i=0;i GetElement(i,&pElement);
hr=pElement->get_CurrentName(&name);
wprintf(L“控件名称:%s\n”,名称);
如果(!lstrcmp(controlName,name))
{
printf(“找到了!\n”);
}
}
}
这里是有效的代码
IUIAutomationElement *zoom = GetTopLevelWindowByName(L"Zoom Meeting");
ListDescendants(zoom, 2);
void ListDescendants(IUIAutomationElement* pParent, int indent)
{
osFocusZoomWindow();
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 sName;
pNode->get_CurrentName(&sName);
//std::wcout << sName << L"\n";
std::wstring strName(sName, SysStringLen(sName));
if (strName.find(L"currently unmuted") != std::string::npos)
{
std::cout<<"####### UNMUTE"<<"\n";
}else if(strName.find(L"currently muted") != std::string::npos){
std::cout<<"####### MUTE"<<"\n";
}
SysFreeString(sName);
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;
}
IUIAutomationElement*zoom=GetToLevel WindowByName(L“缩放会议”);
列表子体(缩放,2);
无效列表子体(IUIAutomationeElement*pParent,int缩进)
{
osFocusZoomWindow();
如果(pParent==NULL)
返回;
IUIAutomationTreeWalker*pControlWalker=NULL;
IUIAutomationeElement*pNode=NULL;
g_pAutomation->get_ControlViewWalker(&pControlWalker);
if(pControlWalker==NULL)
去清理;
pControlWalker->GetFirstChildElement(pParent和pNode);
if(pNode==NULL)
去清理;
while(pNode)
{
BSTR sName;
pNode->get_CurrentName(&sName);
//std::wcout这里是有效的代码
IUIAutomationElement *zoom = GetTopLevelWindowByName(L"Zoom Meeting");
ListDescendants(zoom, 2);
void ListDescendants(IUIAutomationElement* pParent, int indent)
{
osFocusZoomWindow();
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 sName;
pNode->get_CurrentName(&sName);
//std::wcout << sName << L"\n";
std::wstring strName(sName, SysStringLen(sName));
if (strName.find(L"currently unmuted") != std::string::npos)
{
std::cout<<"####### UNMUTE"<<"\n";
}else if(strName.find(L"currently muted") != std::string::npos){
std::cout<<"####### MUTE"<<"\n";
}
SysFreeString(sName);
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;
}
IUIAutomationElement*zoom=GetToLevel WindowByName(L“缩放会议”);
列表子体(缩放,2);
无效列表子体(IUIAutomationeElement*pParent,int缩进)
{
osFocusZoomWindow();
如果(pParent==NULL)
返回;
IUIAutomationTreeWalker*pControlWalker=NULL;
IUIAutomationeElement*pNode=NULL;
g_pAutomation->get_ControlViewWalker(&pControlWalker);
if(pControlWalker==NULL)
去清理;
pControlWalker->GetFirstChildElement(pParent和pNode);
if(pNode==NULL)
去清理;
while(pNode)
{
BSTR sName;
pNode->get_CurrentName(&sName);
//std::wcout,因为您已经发现了包含源代码的文档部分(和)您需要在左侧的树状视图中向上导航,以了解您复制的代码的作用、原因以及如何合并更改,从而使其满足您的需要。@llnspectable谢谢,伙计……但是您能帮我解决这个问题吗,已经花了两天的时间。请使用正确的工具开始。Spy++不会有帮助。will@llnspectable t感谢该工具现在我可以看到其中的所有窗口和元素…@llnspectable我制作了一个函数来列出所有具有递归功能的子代…但它并不是列出所有窗口。以下是代码:以下是所有窗口:因为您已经发现了包含源代码(和)的文档部分您需要在左侧的树状视图中向上导航,以了解您复制的代码的作用、原因以及如何合并更改,从而使其满足您的需要。@llnspectable谢谢,伙计……但是您能帮我解决这个问题吗,已经花了两天的时间。请使用正确的工具开始。Spy++不会有帮助。will@llnspectable t谢谢你的工具,现在我可以看到里面的所有窗口和元素了…@llnspectable我做了一个函数来列出所有具有递归功能的子代…但它并不是列出所有窗口。下面是代码:这里是所有窗口:谢谢你的回复嘿,我做了两个变量IUIAutomation*pClientUIA;IUIAutomationElement*pRootEl全局,所以FindControl可以使用它。但是有一些奇怪的行为代码返回pClientUIA,并且在它不执行后的下一行…尝试了