cxy155194
2015-10-27 02:03
采纳率: 83.3%
浏览 1.9k
已采纳

使用MSA技术获取MS Edge浏览器的输入地址,为什么win10 32位能够获取而64位无法获取?

#include
#pragma comment(lib, "comsuppw.lib")

#include
#include
#include
#pragma comment( lib, "Oleacc.lib")

// --------------------------------------------------------------------------
//
// GetObjectName()
//
// This gets the name of an object.
//
// --------------------------------------------------------------------------
UINT GetObjectName(IAccessible* pacc, VARIANT* pvarChild, LPTSTR lpszName, UINT cchName)
{
CString str;
HRESULT hr;
BSTR bstrName;

*lpszName = 0;
bstrName = NULL;

hr = pacc->get_accName(*pvarChild, &bstrName);

if (SUCCEEDED(hr) && bstrName)
{
    _tcsncpy_s(lpszName, MAX_PATH,bstrName, _tcslen(bstrName));
}

return(lstrlen(lpszName));

}
UINT GetObjectState(IAccessible* pacc, VARIANT* pvarChild, LPTSTR lpszState, UINT cchState)
{
CString str;
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 += GetStateText(dwStateBit, lpszState + cChars, cchState - cChars);
            *(lpszState + cChars++) = ',';
        }
    }
    if(cChars > 1)
        *(lpszState + cChars - 1) = '\0';
}
else if (varRetVal.vt == VT_BSTR)
{
    _tcsncpy_s(lpszState, MAX_PATH, varRetVal.bstrVal, _tcslen(varRetVal.bstrVal));
}

VariantClear(&varRetVal);

return(lstrlen(lpszState));

}

// --------------------------------------------------------------------------
//
// GetObjectClass()
//
// This gets the Class of an object.
//
// --------------------------------------------------------------------------
UINT GetObjectClass(IAccessible* pacc, LPTSTR lpszClass, UINT cchClass)
{
HWND hWnd;
if(S_OK == WindowFromAccessibleObject(pacc, &hWnd))
{
if(hWnd)
GetClassName(hWnd, lpszClass, cchClass);
else
_tcscpy(lpszClass, _T("No window"));
}

return 1;

}

// --------------------------------------------------------------------------
//
// GetObjectRole()
//
// --------------------------------------------------------------------------
UINT GetObjectRole(IAccessible* pacc, VARIANT* pvarChild, LPTSTR lpszRole, UINT cchRole)
{
CString str;
HRESULT hr;
VARIANT varRetVal;

*lpszRole = 0;

VariantInit(&varRetVal);

hr = pacc->get_accRole(*pvarChild, &varRetVal);

if (!SUCCEEDED(hr))
    return(0);

if (varRetVal.vt == VT_I4)
{
    //the function GetRoleText use to translate the int to the Role string.
    GetRoleText(varRetVal.lVal, lpszRole, cchRole);
}
else if (varRetVal.vt == VT_BSTR)
{
    _tcsncpy_s(lpszRole, MAX_PATH, varRetVal.bstrVal, _tcslen(varRetVal.bstrVal));
}

VariantClear(&varRetVal);

return(lstrlen(lpszRole));

}

bool EnumUIChild(IAccessible* paccParent, IAccessible** paccChild, VARIANT* pvarChild)
{
CString str;
HRESULT hr;
long numChildren = 0;
unsigned long numFetched;
VARIANT varChild;
int index;
IAccessible* pCAcc = NULL;
IEnumVARIANT* pEnum = NULL;
IDispatch* pDisp = NULL;
bool found = false;

TCHAR szObjName[MAX_PATH] = {0};
TCHAR szObjRole[MAX_PATH] = {0};
TCHAR szObjClass[MAX_PATH] = {0};
TCHAR szObjState[MAX_PATH] = {0};

//Get the IEnumVARIANT interface
hr = paccParent -> QueryInterface(IID_IEnumVARIANT, (PVOID*) & pEnum);  
if(pEnum)
    pEnum -> Reset();

// Get child count
paccParent -> get_accChildCount(&numChildren);

for(index = 1; (index <= numChildren) && (found == false); index++)
{
    pCAcc = NULL;

    // Get next child
    if (pEnum)
        hr = pEnum -> Next(1, &varChild, &numFetched);  
    else
    {
        //if the farther don't support IEnumVARIANT interface丆
        //ID equal index.
        varChild.vt = VT_I4;
        varChild.lVal = index;
    }

    // Get IDispatch interface for the child
    if (varChild.vt == VT_I4)
    {
        //Get Dispatch interface from ID.
        pDisp = NULL;
        hr = paccParent -> get_accChild(varChild, &pDisp);
    }
    else
        //if the farther support IEnumVARIANT interface, 
        //Get the child's IDispatch interface directly.
        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)
    {
        //if the leaf support IAccessible interface.ID equal CHILDID_SELF
        VariantInit(&varChild);
        varChild.vt = VT_I4;
        varChild.lVal = CHILDID_SELF;

        *paccChild = pCAcc;
    }
    else
        //if the leaf do not support IAccessible interface.
        *paccChild = paccParent;

    // Skip invisible and unavailable objects and their children
    GetObjectState(*paccChild, &varChild, szObjState, sizeof(szObjState));
    if(NULL != _tcsstr(szObjState, _T("unavailable")))
    {
        if(pCAcc)
            pCAcc->Release();
        continue;
    }

    GetObjectName(*paccChild, &varChild, szObjName, sizeof(szObjName));
    GetObjectRole(*paccChild, &varChild, szObjRole, sizeof(szObjRole));
    GetObjectClass(*paccChild, szObjClass, sizeof(szObjClass));

    CString strRole = szObjRole;
    CString strName = szObjName;

    if(/*(0 == strName.Compare(_T("搜索或输入网址")) && 0 == strRole.Compare(_T("可编辑文本"))) || 
        (0 == strName.Compare(_T("Address and search bar")) && 0 == strRole.Compare(_T("editable text"))) ||
        (0 == strName.Compare(_T("Address and search bar")) && 0 == strRole.Compare(_T("可编辑文本"))) ||
        (0 == strName.Compare(_T("搜索或输入网址")) && 0 == strRole.Compare(_T("editable text")))*/
        0 == strRole.Compare(_T("可编辑文本")))
    {
        found = true;
        *pvarChild = varChild;
        break;
    }
    if(!found && pCAcc)
    {   
        found = EnumUIChild(pCAcc, paccChild, pvarChild);
        if(*paccChild != pCAcc)
            pCAcc->Release();

        if(found == true)
            return true;
    }
}

if(pEnum)
    pEnum -> Release();

return found;

}

CString GetURLText()
{
TCHAR szEdit[1024]={0};
HWND hWnd = ::FindWindow(_T("ApplicationFrameWindow"),NULL);
hWnd = ::FindWindowEx(hWnd,0,L"Windows.UI.Core.CoreWindow",NULL);
if(NULL != hWnd)
{
IAccessible paccMainWindow = NULL;
HRESULT hr;
CString strM;
//Get IAccessible Interface Point
if(S_OK == (hr = AccessibleObjectFromWindow(hWnd,
OBJID_WINDOW,
IID_IAccessible,
(void
*)&paccMainWindow)))
{
int index;
BOOL found = false;
IAccessible* paccControl = NULL;
VARIANT varControl;
CoInitialize(NULL);

        if(true == EnumUIChild(paccMainWindow, &paccControl, &varControl))
        {
            BSTR bstrURL;
            hr = paccControl->get_accValue(varControl,&bstrURL);
            if( DISP_E_MEMBERNOTFOUND == hr)
            {
                ::MessageBox(NULL,L"DISP_E_MEMBERNOTFOUND",L"msg",NULL);
            }
            else if( E_INVALIDARG == hr)
            {
                ::MessageBox(NULL,L"E_INVALIDARG",L"msg",NULL);
            }
            else if( S_OK == hr)
            {
                ::MessageBox(NULL,L"S_OK",L"msg",NULL);
            }

            if(SUCCEEDED(hr) &&bstrURL)
            {                           
                char* szEdit1 = _com_util::ConvertBSTRToString(bstrURL); 
                mbstowcs(szEdit, szEdit1, MAX_PATH);
                ::SysFreeString( bstrURL );
            }
            paccControl->Release();
            VariantClear(&varControl);
        };
        paccMainWindow->Release();
    }
}
return szEdit;

}

上面是完整代码,在win10 32位上能够获取到浏览器输入的地址,而win10 64位上找到的地址栏元素无法使用get_accValue()获取网址,根据返回值发现,该对象不支持此属性。

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 邀请回答

1条回答 默认 最新

相关推荐 更多相似问题