IAccessible

Home / C++ MrLee 2017-3-22 4555

本文仅供学习参考,代码是非完整的。可以查阅相关文档完成
开始实现获取子控件IAccessible接口的代码,先看函数定义:
BOOL Find (
    IAccessible* paccParent, 
    LPSTR szName, 
    LPSTR szRole, 
    LPSTR szClass, 
    IAccessible** paccChild, 
    VARIANT* pvarChild)

第一个就是父窗体的IAcessible接口,依次分别为:name, role, classname, 子控件接口,类似于ID的东西(后面再解释) >看实现:
BOOL Find (
    IAccessible* paccParent, 
    LPSTR szName, 
    LPSTR szRole, 
    LPSTR szClass, 
    IAccessible** paccChild, 
    VARIANT* pvarChild)
{
 
    HRESULT hr;
    long numChildren;
    unsigned long numFetched;
    VARIANT varChild;
    int indexCount;
    IAccessible* pCAcc = NULL;
    IEnumVARIANT* pEnum = NULL;
    IDispatch* pDisp = NULL;
    BOOL found = false;
    char szObjName[MAX_PATH], szObjRole[MAX_PATH], szObjClass[MAX_PATH], szObjState[MAX_PATH];
 
    //Get the IEnumVARIANT interface
    hr = paccParent -> QueryInterface(IID_IEnumVARIANT, (PVOID*) & pEnum);
 
    if(pEnum)
        pEnum -> Reset();
 
    // Get child count
    paccParent -> get_accChildCount(&numChildren);
 
    for(indexCount = 1; indexCount <= numChildren && !found; indexCount++)
    {
        pCAcc = NULL;
 
        // Get next child
        if (pEnum)
            hr = pEnum -> Next(1, &varChild, &numFetched);   
        else
        {
            varChild.vt = VT_I4;
            varChild.lVal = indexCount;
        }
 
        // Get IDispatch interface for the child
        if (varChild.vt == VT_I4)
        {
            pDisp = NULL;
            hr = paccParent -> get_accChild(varChild, &pDisp);
        }
        else
            pDisp = varChild.pdispVal;
 
        // Get IAccessible interface for the child
        if (pDisp)
        {
            hr = pDisp->QueryInterface(IID_IAccessible, (void**)&pCAcc);
            hr = pDisp->Release();
        }
 
        // Get information about the child
        if(pCAcc)
        {
            VariantInit(&varChild);
            varChild.vt = VT_I4;
            varChild.lVal = CHILDID_SELF;
 
            *paccChild = pCAcc;
        }
        else
            *paccChild = paccParent;
 
        // Skip invisible and unavailable objects and their children
        GetObjectState(*paccChild, &varChild, szObjState, sizeof(szObjState));
        if(NULL != strstr(szObjState, "unavailable"))
        {
            if(pCAcc)
                pCAcc->Release();
            continue;
        }
 
        GetObjectName(*paccChild, &varChild, szObjName, sizeof(szObjName));
        GetObjectRole(*paccChild, &varChild, szObjRole, sizeof(szObjRole));
        GetObjectClass(*paccChild, szObjClass, sizeof(szObjClass));
 
        if ((!szName || !strcmp(szName, szObjName)) && (!szRole || !strcmp(szRole, szObjRole)) && (!szClass || !strcmp(szClass, szObjClass)))
        {
            found = true;
            *pvarChild = varChild;
            break;
 
        }
        if(!found && pCAcc)
        {
            // Go deeper
            found = Find(pCAcc, szName, szRole, szClass, paccChild, pvarChild);
            if(*paccChild != pCAcc)
                pCAcc->Release();
        }
    }
 
    // Clean up
    if(pEnum)
        pEnum -> Release();
 
    return found;
}

看获取控件状态的函数:
UINT GetObjectState(IAccessible* pacc, VARIANT* pvarChild, LPSTR 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)
    {
        // Convert state flags to comma separated list.
        for (dwStateBit = STATE_SYSTEM_UNAVAILABLE; dwStateBit < STATE_SYSTEM_ALERT_HIGH; dwStateBit <<= 1)
        {
            if (varRetVal.lVal & dwStateBit)
            {
                cChars += GetStateTextA(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(lstrlenA(lpszState));
}

这个是不完整的例子,仅供参考。我自己写的例子没有找到。以后找到了再发上来!

本文链接:https://www.it72.com/11900.htm

推荐阅读
最新回复 (1)
  • richard2015 2017-3-22
    引用 2
    这是我自己的,找到了
    UINT CQMsgHunter::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);
        if (varRetVal.vt == VT_I4)
        {
            // 根据返回的状态值生成以逗号连接的字符串。
            GetStateText(varRetVal.lVal,lpszState,cchState);
        }
        else if (varRetVal.vt == VT_BSTR)
        {
            if(varRetVal.bstrVal)_tcscpy_s(lpszState,cchState,varRetVal.bstrVal);
        }
        VariantClear(&varRetVal);
        return _tcslen(lpszState);
    }
    UINT CQMsgHunter::GetObjectName(IAccessible* pacc,VARIANT* pvarChild,LPTSTR lpszName,UINT cchName)
    {
        HRESULT hr;
        BSTR pszName;
    	hr = pacc->get_accName(*pvarChild,&pszName);
    	if(pszName)_tcscpy_s(lpszName,cchName,pszName);
        return _tcslen(lpszName);
    }
    UINT CQMsgHunter::GetObjectValue(IAccessible* pacc,VARIANT* pvarChild,TCHAR* pValue,UINT cchValue)
    {
        HRESULT hr;
        BSTR pszValue;
        hr = pacc->get_accValue(*pvarChild,&pszValue);
    	if(pszValue)_tcscpy_s(pValue,cchValue,pszValue);
        return _tcslen(pValue);
    }
    UINT CQMsgHunter::GetObjectClass(IAccessible* paccChild,LPTSTR lpszClass,UINT cchClass)
    {
    	HWND hWnd;
    	::WindowFromAccessibleObject(paccChild,&hWnd);
    	if(hWnd)::GetClassName(hWnd,lpszClass,cchClass);
    	return _tcslen(lpszClass);
    }
    UINT CQMsgHunter::GetObjectRole(IAccessible* pacc,VARIANT* pvarChild,LPTSTR lpszRole,UINT cchRole)
    {
        HRESULT hr;
        VARIANT varRetVal;
        *lpszRole = 0;
        VariantInit(&varRetVal);
        hr = pacc->get_accRole(*pvarChild, &varRetVal);
        if (!SUCCEEDED(hr))
            return(0);
        if (varRetVal.vt == VT_I4)
        {
            // 根据返回的状态值生成以逗号连接的字符串。
            GetRoleText(varRetVal.lVal,lpszRole,cchRole);
        }
        else if (varRetVal.vt == VT_BSTR)
        {
    		if(varRetVal.bstrVal)_tcscpy_s(lpszRole,cchRole,varRetVal.bstrVal);
        }
        VariantClear(&varRetVal);
        return(_tcslen(lpszRole));
    }
    
返回