C++ 使用uiautomation和c+;在windows上获取子窗口按钮的标题+;

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

我想在windows上使用uiautomation with C++获取此缩放会议的“静音我的音频”标题。

这是我当前的呼叫代码:

// 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,并且在它不执行后的下一行…尝试了