I'm trying to create a QA automation for Google Chrome, in order to simulate clicks and receive click events on the tab buttons.
I'm using the IAccessible interface and AccessibleChildren API to get the full accessible elements tree.
When using AccExplorer 2.0 to view the tree - it looks great (see image at the end).
But my program shows only a partial tree, and the names do not match the ones I see on AccExplorer.
I'm running:
- Chrome 37 beta
- Win 7 64 bit
Any ideas why I can't view the full tree?
Thanks
This is my program's source (C++) : (similar to MSDN example)
int _tmain(int argc, _TCHAR* argv[])
{
int i=0;
HWND hWndChrome = NULL;
hWndChrome = (HWND)0x000702c0;
wcout << L"\n\nChrome_WidgetWin_1 = "<< hex << hWndChrome << "\n--------------------------";
CComPtr<IAccessible> pAccMain;
::AccessibleObjectFromWindow(hWndChrome, OBJID_CLIENT, IID_IAccessible, (void**)(&pAccMain));
WalkTreeWithAccessibleChildren(pAccMain, 0);
_getch();
return 0;
}
HRESULT WalkTreeWithAccessibleChildren(__in CComPtr<IAccessible> pAcc, __in int depth)
{
long childCount = 0;
long returnCount = 0;
HRESULT hr = pAcc->get_accChildCount(&childCount);
if (childCount == 0)
return S_FALSE;
CComVariant* pArray = new CComVariant[childCount];
hr = ::AccessibleChildren(pAcc, 0L, childCount, pArray, &returnCount);
if (FAILED(hr))
return hr;
// Iterate through children.
for (int x = 0; x < returnCount; x++)
{
CComVariant vtChild = pArray[x];
// If it's an accessible object, get the IAccessible, and recurse.
if (vtChild.vt == VT_DISPATCH)
{
CComPtr<IDispatch> pDisp = vtChild.pdispVal;
CComQIPtr<IAccessible> pAccChild = pDisp;
if (!pAccChild)
continue;
// Print current accessible element
wcout << endl;
for (int y = 0; y < depth; y++) wcout << L" ";
wcout << L"* " << GetName(pAccChild, CHILDID_SELF).data() << L" | " << GetRole(pAccChild, CHILDID_SELF).data() << L" (Object)";
WalkTreeWithAccessibleChildren(pAccChild, depth + 1);
}
// Else it's a child element so we have to call accNavigate on the parent,
// and we do not recurse because child elements can't have children.
else
{
// Print current accessible element
wcout << endl;
for (int y = 0; y < depth; y++) wcout << L" ";
wcout << L"* " << GetName(pAcc, vtChild.lVal).data() << L" | " << GetRole(pAcc, vtChild.lVal).data() << " (Child)";
}
}
delete[] pArray;
return S_OK;
}
wstring GetName(__in CComPtr<IAccessible> pAcc, __in CComVariant varChild)
{
if (!pAcc)
return L"";
CComBSTR bstrName;
HRESULT hr = pAcc->get_accName(varChild, &bstrName);
if (FAILED(hr))
return L"";
if (!bstrName.m_str)
return L"<NULL>";
return bstrName.m_str;
}
wstring GetRole(__in CComPtr<IAccessible> pAcc, __in CComVariant varChild)
{
if (!pAcc)
return L"";
CComVariant varRoleID;
HRESULT hr = pAcc->get_accRole(varChild, &varRoleID);
if (FAILED(hr))
return L"";
WCHAR sRoleBuff[1024] = {0};
hr = ::GetRoleText(varRoleID.lVal, sRoleBuff, 1024);
if (FAILED(hr))
return L"";
return sRoleBuff;
}
And this is the console output:
Chrome_WidgetWin_1 = 000702C0
--------------------------
* Chrome Legacy Window | window (Object)
* System | menu bar (Object)
* <NULL> | title bar (Object)
* IME | push button (Child)
* Minimize | push button (Child)
* Maximize | push button (Child)
* Context help | push button (Child)
* Close | push button (Child)
* Application | menu bar (Object)
* Chrome Legacy Window | client (Object)
// -----> { there should be a big sub-tree here } <----- //
* Vertical | scroll bar (Object)
* Line up | push button (Child)
* Page up | push button (Child)
* Position | indicator (Child)
* Page down | push button (Child)
* Line down | push button (Child)
* Horizontal | scroll bar (Object)
* Column left | push button (Child)
* Page left | push button (Child)
* Position | indicator (Child)
* Page right | push button (Child)
* Column right | push button (Child)
* <NULL> | grip (Object)
Here is an AccExplorer screenshot showing the full tree: (some nodes are collapsed)
Edit:
When Using OBJID_WINDOW instead OBJID_WINDOW (as in the example, in AccessibleObjectFromWindow) - I get a tree with more nodes, but still I can't see the tab elements.