VOID CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook,
				DWORD event,
				HWND hwnd,
				LONG idObject,
				LONG idChild,
				DWORD dwEventThread,
				DWORD dwmsEventTime)
{
	IAccessible* pAcc = NULL;
	VARIANT varChild;
	HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);
	if ((hr == S_OK) && (pAcc != NULL)) {
		BSTR bstrName, bstrValue;
		
		pAcc->get_accValue(varChild, &bstrValue);
		pAcc->get_accName(varChild, &bstrName);

		char className[50];
		GetClassNameA(hwnd, className, 50);

		if ((strcmp(className, "Chrome_WidgetWin_1") == 0) && (wcscmp(bstrName, L"Address and search bar") == 0)) {
			SendMessage(ghWnd, WM_UPDATECAREPOS, NULL, (WPARAM)(bstrValue));//LPCWSTR
			printf("URL change: %ls\n", bstrValue);
		}
		pAcc->Release();
	}

	return;
}
Example #2
0
void CALLBACK WebKitVBufBackend_t::renderThread_winEventProcHook(HWINEVENTHOOK hookID, DWORD eventID, HWND hwnd, long objectID, long childID, DWORD threadID, DWORD time) {
    switch (eventID) {
    case EVENT_OBJECT_VALUECHANGE:
    case EVENT_OBJECT_STATECHANGE:
        break;
    default:
        return;
    }

    WebKitVBufBackend_t* backend = NULL;
    for (VBufBackendSet_t::iterator it = runningBackends.begin(); it != runningBackends.end(); ++it) {
        HWND rootWindow = (HWND)(*it)->rootDocHandle;
        if (hwnd == rootWindow || IsChild(rootWindow, hwnd)) {
            backend = static_cast<WebKitVBufBackend_t*>(*it);
            break;
        }
    }
    if (!backend)
        return;

    IAccessible* acc = IAccessibleFromIdentifier((int)hwnd, childID);
    if (!acc)
        return;
    acc->Release();
    map<IAccessible*, WebKitVBufStorage_controlFieldNode_t*>::const_iterator it;
    if ((it = backend->accessiblesToNodes.find(acc)) == backend->accessiblesToNodes.end())
        return;
    backend->invalidateSubtree(it->second);
}
Example #3
0
void CALLBACK WinEventFunc(HWINEVENTHOOK hook, DWORD dwEvent, HWND hwnd,
                           LONG idObject, LONG idChild,
                           DWORD dwEventThread, DWORD dwmsEventTime) {
  IAccessible* acc = nullptr;
  VARIANT var_child;
  HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &acc,
                                         &var_child);

  if (hr == S_OK && acc != nullptr) {
    BSTR name;
    acc->get_accName(var_child, &name);

    switch (dwEvent) {
      case EVENT_SYSTEM_FOREGROUND:
      case EVENT_SYSTEM_ALERT:
      case EVENT_OBJECT_FOCUS:
      case EVENT_OBJECT_SELECTION:
      case EVENT_OBJECT_VALUECHANGE:
        break;
    }

    SysFreeString(name);
    acc->Release();
  }
}
Example #4
0
LRESULT CALLBACK callWndProcHook(int code, WPARAM wParam,LPARAM lParam) {
    CWPSTRUCT* pcwp = (CWPSTRUCT*)lParam;
    if (pcwp->message == WM_LRESULT_FROM_IACCESSIBLE) {
        *(LRESULT*)pcwp->lParam = LresultFromObject(IID_IAccessible, 0,
                                  (IUnknown*)pcwp->wParam);
    } else if (pcwp->message == WM_IACCESSIBLE_FROM_CHILDID) {
        IAccessible* acc = IAccessibleFromIdentifier((int)pcwp->hwnd, (int)pcwp->wParam);
        if (acc) {
            acc->Release();
        }
        *(IAccessible**) pcwp->lParam = acc;
    }
    return 0;
}
Example #5
0
HRESULT AccessibleObject::BuildChildren(std::vector<AccessibleChild>& children,
                                        IAccessible* acc, LPARAM param) {
  if (acc == nullptr)
    acc = acc_;
  if (acc == nullptr)
    return E_INVALIDARG;

  long child_count = 0;
  HRESULT hr = acc->get_accChildCount(&child_count);

  if (FAILED(hr))
    return hr;
  if (child_count == 0)
    return S_FALSE;

  long obtained_count = 0;
  std::vector<VARIANT> var_array(child_count);
  hr = AccessibleChildren(acc, 0L, child_count, var_array.data(),
                          &obtained_count);

  if (FAILED(hr))
    return hr;

  children.resize(obtained_count);
  for (int i = 0; i < obtained_count; i++) {
    VARIANT var_child = var_array[i];

    if (var_child.vt == VT_DISPATCH) {
      IDispatch* dispatch = var_child.pdispVal;
      IAccessible* child = nullptr;
      hr = dispatch->QueryInterface(IID_IAccessible, (void**)&child);
      if (hr == S_OK) {
        GetName(children.at(i).name, CHILDID_SELF, child);
        GetRole(children.at(i).role, CHILDID_SELF, child);
        GetValue(children.at(i).value, CHILDID_SELF, child);
        if (AllowChildTraverse(children.at(i), param))
          BuildChildren(children.at(i).children, child, param);
        child->Release();
      }
      dispatch->Release();

    } else {
      GetName(children.at(i).name, var_child.lVal, acc);
      GetRole(children.at(i).role, var_child.lVal, acc);
      GetValue(children.at(i).value, var_child.lVal, acc);
    }
  }

  return S_OK;
}
Example #6
0
__declspec( dllexport ) void select_table_row(HMODULE oleAccModule, HWND controlHwnd, long row) {
	IAccessible *pAccessible ;
	LPFNACCESSIBLEOBJECTFROMWINDOW lpfnAccessibleObjectFromWindow ;

	lpfnAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(oleAccModule, "AccessibleObjectFromWindow");

	if (HRESULT hResult = lpfnAccessibleObjectFromWindow(controlHwnd, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible) == S_OK) {
		VARIANT varChild ;
		VariantInit(&varChild) ;
		varChild.vt = VT_I4 ;
		varChild.lVal = row ;

		pAccessible->accSelect(SELFLAG_ADDSELECTION, varChild) ;
	}
}
Example #7
0
bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
{
    if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) {
        /* For UI Automation
      */
    } else if ((DWORD)lParam == OBJID_CLIENT) {
#if 1
        // Ignoring all requests while starting up
        // ### Maybe QPA takes care of this???
        if (QApplication::startingUp() || QApplication::closingDown())
            return false;
#endif

        typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
        static PtrLresultFromObject ptrLresultFromObject = 0;
        static bool oleaccChecked = false;

        if (!oleaccChecked) {
            oleaccChecked = true;
#if !defined(Q_OS_WINCE)
            ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
#endif
        }

        if (ptrLresultFromObject) {
            QWindow *window = QWindowsContext::instance()->findWindow(hwnd);
            if (window) {
                QAccessibleInterface *acc = window->accessibleRoot();
                if (acc) {
                    QWindowsAccessible *winacc = new QWindowsAccessible(acc);
                    IAccessible *iface;
                    HRESULT hr = winacc->QueryInterface(IID_IAccessible, (void**)&iface);
                    if (SUCCEEDED(hr)) {
                        *lResult = ptrLresultFromObject(IID_IAccessible, wParam, iface);  // ref == 2
                        if (*lResult) {
                            iface->Release(); // the client will release the object again, and then it will destroy itself
                        }
                        return true;
                    }
                }
            }
        }
    }
    return false;
}
Example #8
0
void walk_tree(IAccessible *pAccessible, char **pColumnHeaderNames, long *pColumnHeadersCount) {
	HRESULT hr ;
	long childCount ;

	hr = pAccessible->get_accChildCount(&childCount) ;
	if (FAILED(hr) || childCount == 0)
		return ;

	VARIANT *pChildVariants = new VARIANT[childCount] ;
	long childrenFound ;
	hr = AccessibleChildren(pAccessible, 0, childCount, pChildVariants, &childrenFound) ;
	if (FAILED(hr))
		return ;

	for (int i=1; i < childrenFound + 1; i++) {
		VARIANT vChild = pChildVariants[i] ;
		if (vChild.vt == VT_DISPATCH) {
			IDispatch *pDispatch = vChild.pdispVal ;
			IAccessible *pChildAccessible = NULL ;
			hr = pDispatch->QueryInterface(IID_IAccessible, (void**) &pChildAccessible) ;
			if (hr == S_OK) {
				walk_tree(pChildAccessible, pColumnHeaderNames, pColumnHeadersCount) ;

				pChildAccessible->Release() ;
			}

			pDispatch->Release() ;
		} else {
			long role ;
			get_role(i, pAccessible, &role) ;
			if (role == 0x19) {
				if (pColumnHeaderNames == NULL) {
					*pColumnHeadersCount = *pColumnHeadersCount + 1 ;
				} else {
					char *headerName = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
					get_name(i, pAccessible, headerName) ;
					pColumnHeaderNames[i - 1] = headerName ;
				}
			}
		}
	}
}
Example #9
0
LRESULT CALLBACK
WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  // Note, this window's message handling should not invoke any call that
  // may result in a cross-process ipc call. Doing so may violate RPC
  // message semantics.

  switch (msg) {
    case WM_GETOBJECT:
    {
      // Do explicit casting to make it working on 64bit systems (see bug 649236
      // for details).
      int32_t objId = static_cast<DWORD>(lParam);
      if (objId == OBJID_CLIENT) {
        DocAccessible* document =
          nsWinUtils::sHWNDCache->GetWeak(static_cast<void*>(hWnd));
        if (document) {
          IAccessible* msaaAccessible = nullptr;
          document->GetNativeInterface((void**)&msaaAccessible); // does an addref
          if (msaaAccessible) {
            LRESULT result = ::LresultFromObject(IID_IAccessible, wParam,
                                                 msaaAccessible); // does an addref
            msaaAccessible->Release(); // release extra addref
            return result;
          }
        }
      }
      return 0;
    }
    case WM_NCHITTEST:
    {
      LRESULT lRet = ::DefWindowProc(hWnd, msg, wParam, lParam);
      if (HTCLIENT == lRet)
        lRet = HTTRANSPARENT;
      return lRet;
    }
  }

  return ::DefWindowProcW(hWnd, msg, wParam, lParam);
}
Example #10
0
__declspec( dllexport ) long get_table_row_state(HMODULE oleAccModule, HWND controlHwnd, long row) {
	IAccessible *pAccessible ;
	LPFNACCESSIBLEOBJECTFROMWINDOW lpfnAccessibleObjectFromWindow ;

	lpfnAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(oleAccModule, "AccessibleObjectFromWindow");

	if (HRESULT hResult = lpfnAccessibleObjectFromWindow(controlHwnd, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible) == S_OK) {
		VARIANT varChild ;
		VariantInit(&varChild) ;
		varChild.vt = VT_I4 ;
		varChild.lVal = row ;

		VARIANT varState ;

		HRESULT hr = pAccessible->get_accState(varChild, &varState) ;
		if (hr == S_OK) {
			if (varState.vt == VT_I4) {
				return varState.lVal ;
			} else
				return FALSE ;
		} else
			return FALSE ;
	}
}
LRESULT CALLBACK
nsAccessNodeWrap::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  // Note, this window's message handling should not invoke any call that
  // may result in a cross-process ipc call. Doing so may violate RPC
  // message semantics.

  switch (msg) {
    case WM_GETOBJECT:
    {
      if (lParam == OBJID_CLIENT) {
        DocAccessible* document = sHWNDCache.GetWeak(static_cast<void*>(hWnd));
        if (document) {
          IAccessible* msaaAccessible = NULL;
          document->GetNativeInterface((void**)&msaaAccessible); // does an addref
          if (msaaAccessible) {
            LRESULT result = ::LresultFromObject(IID_IAccessible, wParam,
                                                 msaaAccessible); // does an addref
            msaaAccessible->Release(); // release extra addref
            return result;
          }
        }
      }
      return 0;
    }
    case WM_NCHITTEST:
    {
      LRESULT lRet = ::DefWindowProc(hWnd, msg, wParam, lParam);
      if (HTCLIENT == lRet)
        lRet = HTTRANSPARENT;
      return lRet;
    }
  }

  return ::DefWindowProcW(hWnd, msg, wParam, lParam);
}
Example #12
0
IAccessible* IAccessibleFromIdentifier(int docHandle, int ID) {
    // We want to bypass oleacc proxying,
    // so retrieve the IAccessible directly rather than using AccessibleObjectFromEvent.
    LRESULT lres;
    if (!(lres = SendMessage((HWND)docHandle, WM_GETOBJECT, 0, OBJID_CLIENT)))
        return NULL;
    IAccessible* root = NULL;
    if (ObjectFromLresult(lres, IID_IAccessible, 0, (void**)&root) != S_OK)
        return NULL;
    VARIANT varChild;
    varChild.vt = VT_I4;
    varChild.lVal = ID;
    IDispatch* childDisp;
    HRESULT hres = root->get_accChild(varChild, &childDisp);
    root->Release();
    if (hres != S_OK)
        return NULL;
    IAccessible* childAcc;
    hres = childDisp->QueryInterface(IID_IAccessible, (void**)&childAcc);
    childDisp->Release();
    if (hres != S_OK)
        return NULL;
    return childAcc;
}
Example #13
0
void AdobeFlashVBufBackend_t::render(VBufStorage_buffer_t* buffer, int docHandle, int ID, VBufStorage_controlFieldNode_t* oldNode) {
	if (!oldNode) {
		// This is the initial render.
		WCHAR* wclass = (WCHAR*)malloc(sizeof(WCHAR) * 256);
		if (!wclass)
			return;
		if (GetClassName((HWND)UlongToHandle(docHandle), wclass, 256) == 0) {
			free(wclass);
			return;
		}
		this->isWindowless = wcscmp(wclass, L"Internet Explorer_Server") == 0;
		free(wclass);
	}

	DWORD_PTR res=0;
	//Get an IAccessible by sending WM_GETOBJECT directly to bypass any proxying, to speed things up.
	if (SendMessageTimeout((HWND)UlongToHandle(docHandle), WM_GETOBJECT, 0, isWindowless ? ID : OBJID_CLIENT, SMTO_ABORTIFHUNG, 2000, &res) == 0 || res == 0) {
		//Failed to send message or window does not support IAccessible
		return;
	}
	IAccessible* pacc=NULL;
	if(ObjectFromLresult(res,IID_IAccessible,0,(void**)&pacc)!=S_OK) {
		//Could not get the IAccessible pointer from the WM_GETOBJECT result
		return;
	}
	nhAssert(pacc); //must get a valid IAccessible object
	HRESULT hres;
	VARIANT varChild;
	varChild.vt=VT_I4;
	IAccessible* childAcc;
	if (ID != CHILDID_SELF && !this->isWindowless) {
		// We have the root accessible, but a specific child has been requested.
		varChild.lVal = ID;
		IDispatch* childDisp = NULL;
		hres = pacc->get_accChild(varChild, &childDisp);
		pacc->Release();
		if (hres != S_OK || !childDisp)
			return;
		childAcc = NULL;
		hres = childDisp->QueryInterface(IID_IAccessible, (void**)&childAcc);
		childDisp->Release();
		if (hres != S_OK || !childAcc)
			return;
		pacc = childAcc;
	}

	if (!oldNode || ID == this->rootID) {
		// This is the root node.
		VBufStorage_controlFieldNode_t* parentNode=buffer->addControlFieldNode(NULL,NULL,docHandle,ID,TRUE);
		parentNode->addAttribute(L"IAccessible::role",L"10");
		VBufStorage_fieldNode_t* previousNode=NULL;
		long childCount=0;
		pacc->get_accChildCount(&childCount);

		if (this->getAccId(pacc) != -1) {
			// We can get IDs from accessibles.
			VARIANT* varChildren;
			if (!(varChildren = (VARIANT*)malloc(sizeof(VARIANT) * childCount)))
				return;
			if (FAILED(AccessibleChildren(pacc, 0, childCount, varChildren, &childCount)))
				childCount = 0;
			for (long i = 0; i < childCount; ++i) {
				if (varChildren[i].vt != VT_DISPATCH || !varChildren[i].pdispVal) {
					VariantClear(&(varChildren[i]));
					continue;
				}
				childAcc = NULL;
				hres = varChildren[i].pdispVal->QueryInterface(IID_IAccessible, (void**)&childAcc);
				VariantClear(&(varChildren[i]));
				if (hres != S_OK)
					continue;
				int childId = getAccId(childAcc);
				previousNode = this->renderControlContent(buffer, parentNode, previousNode, docHandle, childId, childAcc);
				childAcc->Release();
			}
			free(varChildren);

		} else {
			// We can't get IDs from accessibles.
			// The only way to get IDs is to just try them sequentially.
			// accessiblesByLocation maps ((x, y), id) to (accessible, id).
			// This allows us to order by location and, where that is the same, ID.
			// We need this because added children always have larger IDs,
			// even if they were inserted between two other children.
			map<pair<pair<long, long>, long>, pair<IAccessible*, long>> accessiblesByLocation;
			// Keep going until we have childCount children.
			for(int i=1;i<1000&&static_cast<long>(accessiblesByLocation.size())<childCount;++i) {
				IDispatch* childDisp=NULL;
				varChild.lVal=i;
				if (pacc->get_accChild(varChild, &childDisp) != S_OK || !childDisp)
					continue;
				childAcc = NULL;
				hres = childDisp->QueryInterface(IID_IAccessible, (void**)&childAcc);
				childDisp->Release();
				if (hres != S_OK || !childAcc)
					continue;
				long left=0, top=0, width=0, height=0;
				varChild.lVal = CHILDID_SELF;
				if (childAcc->accLocation(&left, &top, &width, &height, varChild) != S_OK)
					left=top=width=height=0;
				accessiblesByLocation[make_pair(make_pair(top + height / 2, left + width / 2), i)] = make_pair(childAcc, i);
			}
			for (map<pair<pair<long, long>, long>, pair<IAccessible*, long>>::iterator i = accessiblesByLocation.begin(); i != accessiblesByLocation.end(); ++i) {
				previousNode = this->renderControlContent(buffer, parentNode, previousNode, docHandle, i->second.second, i->second.first);
				i->second.first->Release();
			}
		}

	} else {
		// This is a child that is being re-rendered.
		this->renderControlContent(buffer, NULL, NULL, docHandle, ID, pacc);
	}

	pacc->Release();
}
Example #14
0
// Recursively give information about an object
void MyFrame::LogObject(int indent, IAccessible* obj)
{
    wxString name, role;
    if (indent == 0)
    {
        GetInfo(obj, 0, name, role);

        wxString str;
        str.Printf(wxT("Name = %s; Role = %s"), name.c_str(), role.c_str());
        str.Pad(indent, wxT(' '), false);
        Log(str);
    }

    long childCount = 0;
    if (S_OK == obj->get_accChildCount(& childCount))
    {
        wxString str;
        str.Printf(wxT("There are %d children."), (int) childCount);
        str.Pad(indent, wxT(' '), false);
        Log(str);
        Log(wxT(""));
    }

    int i;
    for (i = 1; i <= childCount; i++)
    {
        GetInfo(obj, i, name, role);

        wxString str;
        str.Printf(wxT("%d) Name = %s; Role = %s"), i, name.c_str(), role.c_str());
        str.Pad(indent, wxT(' '), false);
        Log(str);

        VARIANT var;
        VariantInit(& var);
        var.vt = VT_I4;
        var.lVal = i;
        IDispatch* pDisp = NULL;
        IAccessible* childObject = NULL;

        if (S_OK == obj->get_accChild(var, & pDisp) && pDisp)
        {
            wxString str;
            str.Printf(wxT("This is a real object."));
            str.Pad(indent+4, wxT(' '), false);
            Log(str);

            if (pDisp->QueryInterface(IID_IAccessible, (LPVOID*) & childObject) == S_OK)
            {
                LogObject(indent + 4, childObject);
                childObject->Release();
            }
            pDisp->Release();
        }
        else
        {
            wxString str;
            str.Printf(wxT("This is an element."));
            str.Pad(indent+4, wxT(' '), false);
            Log(str);
        }
        // Log(wxT(""));
    }

}
Example #15
0
void MyFrame::OnQuery(wxCommandEvent& WXUNUSED(event))
{
    m_textCtrl->Clear();
    IAccessible* accessibleFrame = NULL;
    if (S_OK != AccessibleObjectFromWindow((HWND) GetHWND(), OBJID_CLIENT,
        IID_IAccessible, (void**) & accessibleFrame))
    {
        Log(wxT("Could not get object."));
        return;
    }
    if (accessibleFrame)
    {
        //Log(wxT("Got an IAccessible for the frame."));
        LogObject(0, accessibleFrame);
        Log(wxT("Checking children using AccessibleChildren()..."));

        // Now check the AccessibleChildren function works OK
        long childCount = 0;
        if (S_OK != accessibleFrame->get_accChildCount(& childCount))
        {
            Log(wxT("Could not get number of children."));
            accessibleFrame->Release();
            return;
        }
        else if (childCount == 0)
        {
            Log(wxT("No children."));
            accessibleFrame->Release();
            return;
        }


        long obtained = 0;
        VARIANT *var = new VARIANT[childCount];
        int i;
        for (i = 0; i < childCount; i++)
        {
            VariantInit(& (var[i]));
            var[i].vt = VT_DISPATCH;
        }

        if (S_OK == AccessibleChildren(accessibleFrame, 0, childCount, var, &obtained))
        {
            for (i = 0; i < childCount; i++)
            {
                IAccessible* childAccessible = NULL;
                if (var[i].pdispVal)
                {
                    if (var[i].pdispVal->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
                    {
                        var[i].pdispVal->Release();

                        wxString name, role;
                        GetInfo(childAccessible, 0, name, role);
                        wxString str;
                        str.Printf(wxT("Found child %s/%s"), name.c_str(), role.c_str());
                        Log(str);
                        childAccessible->Release();
                    }
                    else
                    {
                        var[i].pdispVal->Release();
                    }
                }
            }
        }
        else
        {
            Log(wxT("AccessibleChildren failed."));
        }
        delete[] var;


        accessibleFrame->Release();
    }
}