为什么UI自动化条件无法通过UIA_IsScrollPatternAvailablePropertyId查找元素? [英] Why doesn't UI Automation condition find element by UIA_IsScrollPatternAvailablePropertyId?

查看:121
本文介绍了为什么UI自动化条件无法通过UIA_IsScrollPatternAvailablePropertyId查找元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在允许滚动的主窗口手柄中找到该元素。因此,我没有找到滚动条,而是找到滚动条的所有者,我只想返回允许通过ScrollPattern滚动的项目,因此我在上面设置了条件,但未找到任何内容。如果我搜索滚动条所有者窗口,则可以使用ScrollPattern。为什么我不能仅仅找到具有滚动模式的元素?

I wanted to find the element within a main window handle that allows scrolling. So instead of finding scrollbars and then the owner of the scrollbars I wanted to just return the items that allow scrolling via a ScrollPattern so I setup the condition on that but nothing is found. if I search for scrollbar owner window then get the ScrollPattern it works. Why can't I just find the elements that have a scroll pattern available?

这是常见的代码:

BOOL CUIAutomateScroller::FindWindow(HWND hwnd, IUIAutomationElement **windowelement)
{
  BOOL result=FALSE;
  // make sure init completed
  if (m_pClientUIA) {
    // get window element
    HRESULT hr=m_pClientUIA->ElementFromHandle(hwnd, windowelement);
    // check result
    result=SUCCEEDED(hr);
    // output debug info
    if (FAILED(hr)) {
      CDebugPrint::DebugPrint(_T("ElementFromHandle error: %d\n"), hr);
    }
    else {
      _ASSERT(*windowelement!=NULL);
    }
  }
  return result;
}

BOOL CUIAutomateScroller::FindContainerWindowElement(const long controltype, IUIAutomationElement **pelement)
{
  // Create search condition
  VARIANT varprop;
  varprop.vt=VT_I4;
  varprop.uintVal=controltype;

  CComPtr<IUIAutomationCondition> pcondition;
  HRESULT hr=m_pClientUIA->CreatePropertyCondition(UIA_ControlTypePropertyId, varprop, &pcondition);
  if (FAILED(hr)) {
    CDebugPrint::DebugPrint(_T("CreatePropertyCondition error: %d\n"), hr);
    return NULL;
  }

  // find the control based on condition
  CComPtr<IUIAutomationElementArray> pcontrolelementarr;
  hr=m_pWindowElement->FindAll(TreeScope_Subtree, pcondition, &pcontrolelementarr);
  if (FAILED(hr)) {
    CDebugPrint::DebugPrint(_T("CreatePropertyCondition error: %d\n"), hr);
    return NULL;
  }

  // get number of controls found
  int numfound;
  pcontrolelementarr->get_Length(&numfound);
  CDebugPrint::DebugPrint(_T("Controls Found: %d\n"), numfound);

  // process controls found, but really we exit earily if container window found
  for (int i=0; i < numfound; i++) {
    // get individual control element
    CComPtr<IUIAutomationElement> pcontrolelement;
    hr=pcontrolelementarr->GetElement(i, &pcontrolelement);
    if (FAILED(hr)) {
      // skip element unable to be retreived
      CDebugPrint::DebugPrint(_T("GetElement error: %d\n"), hr);
      continue;
    }

    // output debug information
    CComBSTR name;
    hr=pcontrolelement->get_CurrentName(&name);
    if (FAILED(hr)) {
      CDebugPrint::DebugPrint(_T("GetCurrentName error: %d\n"), hr);
    }
    CDebugPrint::DebugPrint(_T("Control Name: %s\n"), name);
    name.Empty();

    hr=pcontrolelement->get_CurrentClassName(&name);
    if (FAILED(hr)) {
      CDebugPrint::DebugPrint(_T("GetCurrentClass error: %d\n"), hr);
    }
    CDebugPrint::DebugPrint(_T("Class Name: %s\n"), name);
    name.Empty();

    CComPtr<IUIAutomationTreeWalker> pcontentwalker=NULL;
    hr=m_pClientUIA->get_ContentViewWalker(&pcontentwalker);
    if (pcontentwalker == NULL) {
      return NULL;
    }

    // Get ancestor element nearest to the scrollbar UI Automation element in the tree view
    hr=pcontentwalker->NormalizeElement(pcontrolelement, pelement);
    if (FAILED(hr)) {
      CDebugPrint::DebugPrint(_T("NormalizeElement error: %d\n"), hr);
      return NULL;
    }

    // output debug information
    hr=(*pelement)->get_CurrentName(&name);
    if (FAILED(hr)) {
      CDebugPrint::DebugPrint(_T("get_CurrentName error: %d\n"), hr);
    }
    CDebugPrint::DebugPrint(_T("Ancestor Name: %s\n"), name);
    name.Empty();

    return TRUE;
  }

  return FALSE;
}

这不起作用(找不到任何东西):

This does NOT work (It doesn't find anything):

  // get main window
  if (FindWindow(hwnd, &m_pWindowElement)) {
    HRESULT hr;
    VARIANT varprop;
      
    // create condition for elements that have UIA_IsScrollPatternAvailablePropertyId available
    CComPtr<IUIAutomationCondition> pscrollpatterncondition;
    varprop.vt=VT_BOOL;
    varprop.boolVal=TRUE;
    hr=m_pClientUIA->CreatePropertyCondition(UIA_IsScrollPatternAvailablePropertyId, varprop, &pscrollpatterncondition);
    // check result
    if (FAILED(hr)) {
      CDebugPrint::DebugPrint(_T("CreatePropertyCondition for ScrollPattern Error: %d\n"), hr);
    }
    else {
      // find the matching element
      CComPtr<IUIAutomationElementArray> pscrollpatternarr;
      hr=m_pWindowElement->FindAll(TreeScope_Subtree, pscrollpatterncondition, &pscrollpatternarr);
      // check result (normal is success with empty array if not found)
      if (FAILED(hr)) {
        CDebugPrint::DebugPrint(_T("FindAll Error: %d\n"), hr);
      }
      else {
        // get number of elements in array
        int numfound=0;
        pscrollpatternarr->get_Length(&numfound);
        // make sure we only get one scrollable area - in the future we could figure out the rect
        // **numfound is 0**

此功能有效:

  // get main window
  if (FindWindow(hwnd, &m_pWindowElement)) {
    // get scrollable window element based on scrollbar
    if (FindContainerWindowElement(UIA_ScrollBarControlTypeId, &m_pScrollableElement)) {
      HRESULT hr;
      // get the scroll pattern
      hr=m_pScrollableElement->GetCurrentPattern(UIA_ScrollPatternId, (IUnknown**) &m_pScrollPattern);
      if (FAILED(hr)) {
        CDebugPrint::DebugPrint(_T("GetCurrentPattern for Scroll Pattern Error %d:\n"), hr);
      }
      else if (m_pScrollPattern!=NULL) {
        // **we're good!!**


推荐答案


为什么我不能仅仅找到具有滚动模式
的元素?

Why can't I just find the elements that have a scroll pattern available?

@HansPassant指出,请使用 VARIANT_TRUE -1 )而不是 TRUE 1 )。

As @HansPassant pointed out, use VARIANT_TRUE (-1) instead of TRUE (1).

更正以上错误后,以下代码为我工作,查找具有滚动模式( IUIAutomationScrollPattern )且滚动(垂直滚动条)。

After correct above error the following code work for me for finding the elements that have a scroll pattern (IUIAutomationScrollPattern) available and scrolling (vertical scrollbar).

    VARIANT varprop;

    // create condition for elements that have UIA_IsScrollPatternAvailablePropertyId available
    CComPtr<IUIAutomationCondition> pscrollpatterncondition;
    varprop.vt = VT_BOOL;
    varprop.boolVal = VARIANT_TRUE;
    hr = m_pClientUIA->CreatePropertyCondition(UIA_IsScrollPatternAvailablePropertyId, varprop, &pscrollpatterncondition);
    // check result
    if (FAILED(hr)) {
    }
    else {
        // find the matching element
        CComPtr<IUIAutomationElementArray> pscrollpatternarr;
        hr = m_pWindowElement->FindAll(TreeScope_Subtree, pscrollpatterncondition, &pscrollpatternarr);
        // check result (normal is success with empty array if not found)
        if (FAILED(hr)) {
        }
        else {
            // get number of elements in array
            numfound = 0;
            pscrollpatternarr->get_Length(&numfound);
            for (int i = 0; i < numfound; i++)
            {
                IUIAutomationElement *element = NULL;
                pscrollpatternarr->GetElement(i, &element);

                IUIAutomationScrollPattern  *m_pScrollPattern = NULL;
                hr = element->GetCurrentPattern(UIA_ScrollPatternId, (IUnknown**)&m_pScrollPattern);
                if (FAILED(hr)) {
                }
                else if (m_pScrollPattern != NULL) {
                    // Scroll vertical scrollbar
                    m_pScrollPattern->Scroll(ScrollAmount_NoAmount, ScrollAmount_LargeIncrement);
                }
            }
        }
    }

这篇关于为什么UI自动化条件无法通过UIA_IsScrollPatternAvailablePropertyId查找元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆