WEB开发网
开发学院软件开发VC MS Active Accessibility 接口技术编程尝试 阅读

MS Active Accessibility 接口技术编程尝试

 2006-07-20 11:39:00 来源:WEB开发网   
核心提示: 第二、三、四个参数分别是名字、角色、类,后2个为返回参数包含了 IAccessible 接口/子ID对,MS Active Accessibility 接口技术编程尝试(5),下面是FindChild的实现,BOOL FindChild (IAccessible* paccParent,

第二、三、四个参数分别是名字、角色、类。

后2个为返回参数包含了 IAccessible 接口/子ID对。下面是FindChild的实现。

BOOL FindChild (IAccessible* paccParent,
             LPSTR szName, LPSTR szRole,
             LPSTR szClass,
             IAccessible** paccChild,
             VARIANT* pvarChild)
{
  HRESULT hr;
  long numChildren;
  unsigned long numFetched;
  VARIANT varChild;
  int index;
  IAccessible* pCAcc = NULL;
  IEnumVARIANT* pEnum = NULL;
  IDispatch* pDisp = NULL;
  BOOL found = false;
  char szObjName[256], szObjRole[256], szObjClass[256], szObjState[256];
  
    //得到父亲支持的IEnumVARIANT接口
  hr = paccParent -> QueryInterface(IID_IEnumVARIANT, (PVOID*) & pEnum);
  
  if(pEnum)
    pEnum -> Reset();
  
//取得父亲拥有的可访问的子的数目
  paccParent -> get_accChildCount(&numChildren);
  
//搜索并比较每一个子ID,找到名字、角色、类与输入相一致的。
  for(index = 1; index <= numChildren && !found; index++)
  {
    pCAcc = NULL;    
    // 如果支持IEnumVARIANT接口,得到下一个子ID
//以及其对应的 IDispatch 接口
    if (pEnum)
      hr = pEnum -> Next(1, &varChild, &numFetched);  
    else
  {
    //如果一个父亲不支持IEnumVARIANT接口,子ID就是它的序号
      varChild.vt = VT_I4;
      varChild.lVal = index;
    }
    
    // 找到此子ID对应的 IDispatch 接口
    if (varChild.vt == VT_I4)
    {
      //通过子ID序号得到对应的 IDispatch 接口
      pDisp = NULL;
      hr = paccParent -> get_accChild(varChild, &pDisp);
    }
    else
      //如果父支持IEnumVARIANT接口可以直接得到子IDispatch 接口
      pDisp = varChild.pdispVal;
    
    // 通过 IDispatch 接口得到子的 IAccessible 接口 pCAcc
    if (pDisp)
    {
      hr = pDisp->QueryInterface(IID_IAccessible, (void**)&pCAcc);
      hr = pDisp->Release();
    }
    
    // Get information about the child
    if(pCAcc)
    {
      //如果子支持IAccessible 接口,那么子ID就是CHILDID_SELF
      VariantInit(&varChild);
      varChild.vt = VT_I4;
      varChild.lVal = CHILDID_SELF;
      
      *paccChild = pCAcc;
    }
    else
      //如果子不支持IAccessible 接口
      *paccChild = paccParent;
    
    //跳过了有不可访问状态的元素
    GetObjectState(*paccChild,
            &varChild,
            szObjState,
            sizeof(szObjState));
    if(NULL != strstr(szObjState, "unavailable"))
    {
      if(pCAcc)
        pCAcc->Release();
      continue;
    }
    //通过get_accName得到Name
    GetObjectName(*paccChild, &varChild, szObjName, sizeof(szObjName));
    //通过get_accRole得到Role
    GetObjectRole(*paccChild, &varChild, szObjRole, sizeof(szObjRole));
    //通过WindowFromAccessibleObject和GetClassName得到Class
    GetObjectClass(*paccChild, szObjClass, sizeof(szObjClass));
    //以上实现代码比较简单,大家自己看代码吧。
      //如果这些参数与输入相符或输入为NULL
    if ((!szName ||
       !strcmp(szName, szObjName)) &&
       (!szRole ||
       !strcmp(szRole, szObjRole)) &&
       (!szClass ||
       !strcmp(szClass, szObjClass)))
    {
      found = true;
      *pvarChild = varChild;
      break;
    }
    if(!found && pCAcc)
    {
      // 以这次得到的子接口为父递归调用
      found = FindChild(pCAcc,
               szName,
               szRole,
               szClass,
               paccChild,
               pvarChild);
      if(*paccChild != pCAcc)
        pCAcc->Release();
    }
  }//End for
  
  // Clean up
  if(pEnum)
    pEnum -> Release();
  
  return found;
}
// UI元素的状态也表示成整型形式。因为一个状态可以有多个值,
//例如可选的、可做焦点的,该整数是反映这些值的位的或操作结果。
//将这些或数转换成相应的用逗号分割的状态字符串。
UINT GetObjectState(IAccessible* pacc,
          VARIANT* pvarChild,
          LPTSTR lpszState,
          UINT cchState)
{
  HRESULT hr;
  VARIANT varRetVal;
  
  *lpszState = 0;
  
  VariantInit(&varRetVal);
  
  hr = pacc->get_accState(*pvarChild, &varRetVal);
  
  if (!SUCCEEDED(hr))
    return(0);
  
  DWORD dwStateBit;
  int cChars = 0;
  if (varRetVal.vt == VT_I4)
  {
    // 根据返回的状态值生成以逗号连接的字符串。
    for (dwStateBit = STATE_SYSTEM_UNAVAILABLE;
        dwStateBit < STATE_SYSTEM_ALERT_HIGH;
        dwStateBit <<= 1)
    {
      if (varRetVal.lVal & dwStateBit)
      {
        cChars += GetStateText(dwStateBit,
                    lpszState + cChars,
                    cchState - cChars);
        *(lpszState + cChars++) = '','';
      }
    }
    if(cChars > 1)
      *(lpszState + cChars - 1) = ''\0'';
  }
  else if (varRetVal.vt == VT_BSTR)
  {
    WideCharToMultiByte(CP_ACP,
              0,
              varRetVal.bstrVal,
              -1,
              lpszState,
              cchState,
              NULL,
              NULL);
  }
  
  VariantClear(&varRetVal);
  
  return(lstrlen(lpszState));
}

好了!!我们已经成功得到文本框的 IAccessible 接口指针了!!现在你可以用这个接口指针为所欲为了!!!呵呵:)

上一页  1 2 3 4 5 6 7 8 9  下一页

Tags:MS Active Accessibility

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接