2003-04-01 20:02:51 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
#include "nsAccessibleWrap.h"
|
2010-04-27 06:52:03 +00:00
|
|
|
|
2011-12-06 06:07:46 +00:00
|
|
|
#include "Compatibility.h"
|
2012-05-26 12:14:21 +00:00
|
|
|
#include "EnumVariant.h"
|
2010-04-27 06:52:03 +00:00
|
|
|
#include "nsAccUtils.h"
|
|
|
|
#include "nsCoreUtils.h"
|
2010-09-17 03:23:17 +00:00
|
|
|
#include "nsWinUtils.h"
|
2011-08-10 01:44:00 +00:00
|
|
|
#include "Relation.h"
|
2012-01-12 03:07:35 +00:00
|
|
|
#include "Role.h"
|
2011-04-09 23:38:06 +00:00
|
|
|
#include "States.h"
|
2007-04-16 20:23:00 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
#include "ia2AccessibleRelation.h"
|
|
|
|
|
2007-04-16 20:23:00 +00:00
|
|
|
#include "nsIAccessibleEvent.h"
|
2011-08-10 01:44:00 +00:00
|
|
|
#include "nsIAccessibleRelation.h"
|
2007-03-18 05:21:13 +00:00
|
|
|
|
|
|
|
#include "Accessible2_i.c"
|
2012-04-26 18:25:33 +00:00
|
|
|
#include "AccessibleRole.h"
|
2007-03-18 15:54:48 +00:00
|
|
|
#include "AccessibleStates.h"
|
2012-05-04 06:09:22 +00:00
|
|
|
#include "RootAccessible.h"
|
2007-03-18 05:21:13 +00:00
|
|
|
|
2006-04-12 15:43:32 +00:00
|
|
|
#include "nsIMutableArray.h"
|
2004-05-25 14:37:07 +00:00
|
|
|
#include "nsIDOMDocument.h"
|
2005-03-02 19:05:09 +00:00
|
|
|
#include "nsIFrame.h"
|
2005-08-18 16:35:49 +00:00
|
|
|
#include "nsIScrollableFrame.h"
|
2005-03-02 19:05:09 +00:00
|
|
|
#include "nsINameSpaceManager.h"
|
2005-01-21 03:50:26 +00:00
|
|
|
#include "nsINodeInfo.h"
|
2004-05-25 14:37:07 +00:00
|
|
|
#include "nsIServiceManager.h"
|
2005-03-27 03:29:53 +00:00
|
|
|
#include "nsTextFormatter.h"
|
2005-03-02 19:05:09 +00:00
|
|
|
#include "nsIView.h"
|
2009-09-09 05:40:01 +00:00
|
|
|
#include "nsIViewManager.h"
|
2007-04-16 20:23:00 +00:00
|
|
|
#include "nsEventMap.h"
|
2007-01-20 12:43:08 +00:00
|
|
|
#include "nsArrayUtils.h"
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2012-04-26 18:25:33 +00:00
|
|
|
#include "OLEACC.H"
|
|
|
|
|
|
|
|
using namespace mozilla;
|
2011-07-27 12:43:01 +00:00
|
|
|
using namespace mozilla::a11y;
|
|
|
|
|
2012-04-26 18:25:33 +00:00
|
|
|
const PRUint32 USE_ROLE_STRING = 0;
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
/* For documentation of the accessibility architecture,
|
2003-04-01 20:02:51 +00:00
|
|
|
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
//#define DEBUG_LEAKS
|
|
|
|
|
|
|
|
#ifdef DEBUG_LEAKS
|
|
|
|
static gAccessibles = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
EXTERN_C GUID CDECL CLSID_Accessible =
|
|
|
|
{ 0x61044601, 0xa811, 0x4e2b, { 0xbb, 0xba, 0x17, 0xbf, 0xab, 0xd3, 0x29, 0xd7 } };
|
|
|
|
|
2008-07-08 14:23:18 +00:00
|
|
|
static const PRInt32 kIEnumVariantDisconnected = -1;
|
|
|
|
|
2010-06-11 08:23:18 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccessibleWrap
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2012-01-06 03:45:27 +00:00
|
|
|
ITypeInfo* nsAccessibleWrap::gTypeInfo = NULL;
|
|
|
|
|
2007-05-01 17:08:26 +00:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED0(nsAccessibleWrap, nsAccessible);
|
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
//-----------------------------------------------------
|
|
|
|
// IUnknown interface methods - see iunknown.h for documentation
|
|
|
|
//-----------------------------------------------------
|
|
|
|
|
2003-04-15 08:45:55 +00:00
|
|
|
// Microsoft COM QueryInterface
|
2003-04-01 20:02:51 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
*ppv = NULL;
|
|
|
|
|
|
|
|
if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid)
|
2007-07-08 07:08:04 +00:00
|
|
|
*ppv = static_cast<IAccessible*>(this);
|
2011-05-12 11:37:18 +00:00
|
|
|
else if (IID_IEnumVARIANT == iid) {
|
2012-05-26 12:14:21 +00:00
|
|
|
// Don't support this interface for leaf elements.
|
|
|
|
if (!HasChildren() || nsAccUtils::MustPrune(this))
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
|
|
|
|
*ppv = static_cast<IEnumVARIANT*>(new ChildrenEnumVariant(this));
|
2007-03-18 05:21:13 +00:00
|
|
|
} else if (IID_IServiceProvider == iid)
|
2007-07-08 07:08:04 +00:00
|
|
|
*ppv = static_cast<IServiceProvider*>(this);
|
2011-12-06 06:07:46 +00:00
|
|
|
else if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off())
|
2007-07-08 07:08:04 +00:00
|
|
|
*ppv = static_cast<IAccessible2*>(this);
|
2007-05-16 04:28:38 +00:00
|
|
|
|
2007-05-16 06:04:20 +00:00
|
|
|
if (NULL == *ppv) {
|
2012-04-13 15:46:37 +00:00
|
|
|
HRESULT hr = ia2AccessibleComponent::QueryInterface(iid, ppv);
|
2007-05-16 06:04:20 +00:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2007-05-16 04:28:38 +00:00
|
|
|
if (NULL == *ppv) {
|
|
|
|
HRESULT hr = CAccessibleHyperlink::QueryInterface(iid, ppv);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
return hr;
|
|
|
|
}
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2007-05-09 08:19:01 +00:00
|
|
|
if (NULL == *ppv) {
|
|
|
|
HRESULT hr = CAccessibleValue::QueryInterface(iid, ppv);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
if (NULL == *ppv)
|
|
|
|
return nsAccessNodeWrap::QueryInterface(iid, ppv);
|
2006-02-28 14:35:50 +00:00
|
|
|
|
2007-07-08 07:08:04 +00:00
|
|
|
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2012-05-26 12:14:21 +00:00
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------
|
|
|
|
// IAccessible methods
|
|
|
|
//-----------------------------------------------------
|
|
|
|
|
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-15 08:45:55 +00:00
|
|
|
*ppdispParent = NULL;
|
2005-08-18 16:35:49 +00:00
|
|
|
|
2010-09-17 03:23:17 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2010-09-17 03:23:17 +00:00
|
|
|
|
2012-04-10 05:55:18 +00:00
|
|
|
nsDocAccessible* doc = AsDoc();
|
2010-09-17 03:23:17 +00:00
|
|
|
if (doc) {
|
|
|
|
// Return window system accessible object for root document and tab document
|
|
|
|
// accessibles.
|
|
|
|
if (!doc->ParentDocument() ||
|
2011-03-28 13:59:36 +00:00
|
|
|
nsWinUtils::IsWindowEmulationStarted() &&
|
2011-07-22 00:49:35 +00:00
|
|
|
nsCoreUtils::IsTabDocument(doc->GetDocumentNode())) {
|
2010-09-17 03:23:17 +00:00
|
|
|
HWND hwnd = static_cast<HWND>(doc->GetNativeWindow());
|
2012-02-02 12:29:58 +00:00
|
|
|
if (hwnd && SUCCEEDED(::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
|
|
|
|
IID_IAccessible,
|
|
|
|
(void**)ppdispParent))) {
|
2010-09-17 03:23:17 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
2005-03-02 19:05:09 +00:00
|
|
|
}
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2011-07-23 08:38:33 +00:00
|
|
|
nsAccessible* xpParentAcc = Parent();
|
2011-02-22 13:54:46 +00:00
|
|
|
if (!xpParentAcc) {
|
|
|
|
if (IsApplication())
|
|
|
|
return S_OK;
|
2010-01-11 14:14:06 +00:00
|
|
|
|
2011-02-22 13:54:46 +00:00
|
|
|
NS_ERROR("No parent accessible. Should we really assert here?");
|
2005-08-18 16:35:49 +00:00
|
|
|
return E_UNEXPECTED;
|
2011-02-22 13:54:46 +00:00
|
|
|
}
|
2010-01-11 14:14:06 +00:00
|
|
|
|
|
|
|
*ppdispParent = NativeAccessible(xpParentAcc);
|
2005-03-02 19:05:09 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2005-03-02 19:05:09 +00:00
|
|
|
return S_OK;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2011-08-04 03:57:22 +00:00
|
|
|
if (!pcountChildren)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2006-07-12 13:14:53 +00:00
|
|
|
*pcountChildren = 0;
|
2011-08-04 03:57:22 +00:00
|
|
|
|
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2011-08-04 03:57:22 +00:00
|
|
|
|
2008-10-17 10:10:43 +00:00
|
|
|
if (nsAccUtils::MustPrune(this))
|
2011-08-04 03:57:22 +00:00
|
|
|
return S_OK;
|
2006-07-12 13:14:53 +00:00
|
|
|
|
2012-05-25 10:53:45 +00:00
|
|
|
*pcountChildren = ChildCount();
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accChild(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
*ppdispChild = NULL;
|
2010-09-09 14:44:56 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2010-09-09 14:44:56 +00:00
|
|
|
// IAccessible::accChild is used to return this accessible or child accessible
|
|
|
|
// at the given index or to get an accessible by child ID in the case of
|
|
|
|
// document accessible (it's handled by overriden GetXPAccessibleFor method
|
|
|
|
// on the document accessible). The getting an accessible by child ID is used
|
|
|
|
// by AccessibleObjectFromEvent() called by AT when AT handles our MSAA event.
|
|
|
|
nsAccessible* child = GetXPAccessibleFor(varChild);
|
2012-04-09 14:45:47 +00:00
|
|
|
if (!child)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (child->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
*ppdispChild = NativeAccessible(child);
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
return S_OK;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accName(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ BSTR __RPC_FAR *pszName)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
*pszName = NULL;
|
2012-04-09 14:45:47 +00:00
|
|
|
|
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
2008-04-24 06:01:28 +00:00
|
|
|
if (!xpAccessible)
|
2012-04-09 14:45:47 +00:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2008-04-24 06:01:28 +00:00
|
|
|
nsAutoString name;
|
2012-05-01 03:08:31 +00:00
|
|
|
xpAccessible->Name(name);
|
2011-11-17 06:37:27 +00:00
|
|
|
|
|
|
|
// The name was not provided, e.g. no alt attribute for an image. A screen
|
|
|
|
// reader may choose to invent its own accessible name, e.g. from an image src
|
|
|
|
// attribute. Refer to NS_OK_EMPTY_NAME return value.
|
|
|
|
if (name.IsVoid())
|
|
|
|
return S_FALSE;
|
2008-03-16 01:17:38 +00:00
|
|
|
|
2008-04-24 06:01:28 +00:00
|
|
|
*pszName = ::SysAllocStringLen(name.get(), name.Length());
|
|
|
|
if (!*pszName)
|
|
|
|
return E_OUTOFMEMORY;
|
2008-03-16 01:17:38 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accValue(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ BSTR __RPC_FAR *pszValue)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
*pszValue = NULL;
|
2011-12-01 16:11:53 +00:00
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2011-12-01 16:11:53 +00:00
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
2012-04-09 14:45:47 +00:00
|
|
|
if (!xpAccessible)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2011-12-01 16:11:53 +00:00
|
|
|
|
2012-04-09 09:48:41 +00:00
|
|
|
if (xpAccessible->NativeRole() == roles::PASSWORD_TEXT)
|
|
|
|
return E_ACCESSDENIED;
|
|
|
|
|
2011-12-01 16:11:53 +00:00
|
|
|
nsAutoString value;
|
2012-04-09 09:48:41 +00:00
|
|
|
xpAccessible->Value(value);
|
2011-12-01 16:11:53 +00:00
|
|
|
|
|
|
|
// See bug 438784: need to expose URL on doc's value attribute. For this,
|
|
|
|
// reverting part of fix for bug 425693 to make this MSAA method behave
|
|
|
|
// IAccessible2-style.
|
|
|
|
if (value.IsEmpty())
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
*pszValue = ::SysAllocStringLen(value.get(), value.Length());
|
|
|
|
if (!*pszValue)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-27 12:17:11 +00:00
|
|
|
STDMETHODIMP
|
|
|
|
nsAccessibleWrap::get_accDescription(VARIANT varChild,
|
|
|
|
BSTR __RPC_FAR *pszDescription)
|
2005-03-27 03:29:53 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2007-03-27 12:17:11 +00:00
|
|
|
*pszDescription = NULL;
|
2008-02-09 02:40:47 +00:00
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
|
|
|
if (!xpAccessible)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2007-03-27 12:17:11 +00:00
|
|
|
|
|
|
|
nsAutoString description;
|
2011-04-23 13:14:05 +00:00
|
|
|
xpAccessible->Description(description);
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2008-03-16 01:17:38 +00:00
|
|
|
*pszDescription = ::SysAllocStringLen(description.get(),
|
|
|
|
description.Length());
|
|
|
|
return *pszDescription ? S_OK : E_OUTOFMEMORY;
|
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2008-03-16 01:17:38 +00:00
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accRole(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarRole)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
VariantInit(pvarRole);
|
|
|
|
|
2010-09-14 23:22:09 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2010-09-14 23:22:09 +00:00
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
2003-04-01 20:02:51 +00:00
|
|
|
if (!xpAccessible)
|
2012-04-09 14:45:47 +00:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2012-05-07 23:49:41 +00:00
|
|
|
#ifdef DEBUG
|
2008-10-17 10:10:43 +00:00
|
|
|
NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(xpAccessible),
|
|
|
|
"Does not support nsIAccessibleText when it should");
|
2006-11-08 08:22:46 +00:00
|
|
|
#endif
|
|
|
|
|
2012-04-26 18:25:33 +00:00
|
|
|
a11y::role geckoRole = xpAccessible->Role();
|
|
|
|
PRUint32 msaaRole = 0;
|
|
|
|
|
|
|
|
#define ROLE(_geckoRole, stringRole, atkRole, macRole, _msaaRole, ia2Role) \
|
|
|
|
case roles::_geckoRole: \
|
|
|
|
msaaRole = _msaaRole; \
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (geckoRole) {
|
|
|
|
#include "RoleMap.h"
|
|
|
|
default:
|
|
|
|
MOZ_NOT_REACHED("Unknown role.");
|
|
|
|
};
|
|
|
|
|
|
|
|
#undef ROLE
|
2006-06-16 17:13:37 +00:00
|
|
|
|
2007-07-04 07:52:18 +00:00
|
|
|
// Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call the MSAA role
|
|
|
|
// a ROLE_OUTLINEITEM for consistency and compatibility.
|
|
|
|
// We need this because ARIA has a role of "row" for both grid and treegrid
|
2012-04-26 18:25:33 +00:00
|
|
|
if (geckoRole == roles::ROW) {
|
2011-07-23 08:38:33 +00:00
|
|
|
nsAccessible* xpParent = Parent();
|
2012-01-12 03:07:35 +00:00
|
|
|
if (xpParent && xpParent->Role() == roles::TREE_TABLE)
|
2007-07-04 07:52:18 +00:00
|
|
|
msaaRole = ROLE_SYSTEM_OUTLINEITEM;
|
|
|
|
}
|
|
|
|
|
2005-01-21 03:50:26 +00:00
|
|
|
// -- Try enumerated role
|
2006-07-17 14:53:36 +00:00
|
|
|
if (msaaRole != USE_ROLE_STRING) {
|
2005-01-21 03:50:26 +00:00
|
|
|
pvarRole->vt = VT_I4;
|
2006-07-17 14:53:36 +00:00
|
|
|
pvarRole->lVal = msaaRole; // Normal enumerated role
|
2005-01-21 03:50:26 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- Try BSTR role
|
|
|
|
// Could not map to known enumerated MSAA role like ROLE_BUTTON
|
|
|
|
// Use BSTR role to expose role attribute or tag name + namespace
|
2010-06-11 08:23:18 +00:00
|
|
|
nsIContent *content = xpAccessible->GetContent();
|
2007-03-10 03:00:08 +00:00
|
|
|
if (!content)
|
|
|
|
return E_FAIL;
|
|
|
|
|
2010-04-30 13:12:06 +00:00
|
|
|
if (content->IsElement()) {
|
2005-01-21 03:50:26 +00:00
|
|
|
nsAutoString roleString;
|
2007-12-12 02:10:26 +00:00
|
|
|
if (msaaRole != ROLE_SYSTEM_CLIENT &&
|
2011-06-03 21:35:17 +00:00
|
|
|
!content->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roleString)) {
|
2009-07-23 07:12:57 +00:00
|
|
|
nsIDocument * document = content->GetCurrentDoc();
|
|
|
|
if (!document)
|
|
|
|
return E_FAIL;
|
|
|
|
|
2005-09-24 18:43:15 +00:00
|
|
|
nsINodeInfo *nodeInfo = content->NodeInfo();
|
|
|
|
nodeInfo->GetName(roleString);
|
2009-07-23 07:12:57 +00:00
|
|
|
|
|
|
|
// Only append name space if different from that of current document.
|
|
|
|
if (!nodeInfo->NamespaceEquals(document->GetDefaultNamespaceID())) {
|
|
|
|
nsAutoString nameSpaceURI;
|
|
|
|
nodeInfo->GetNamespaceURI(nameSpaceURI);
|
2005-09-24 18:43:15 +00:00
|
|
|
roleString += NS_LITERAL_STRING(", ") + nameSpaceURI;
|
|
|
|
}
|
2006-02-28 14:35:50 +00:00
|
|
|
}
|
2009-07-23 07:12:57 +00:00
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
if (!roleString.IsEmpty()) {
|
|
|
|
pvarRole->vt = VT_BSTR;
|
|
|
|
pvarRole->bstrVal = ::SysAllocString(roleString.get());
|
|
|
|
return S_OK;
|
2005-01-21 03:50:26 +00:00
|
|
|
}
|
|
|
|
}
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2005-01-21 03:50:26 +00:00
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accState(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarState)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
VariantInit(pvarState);
|
|
|
|
pvarState->vt = VT_I4;
|
|
|
|
pvarState->lVal = 0;
|
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
2003-04-01 20:02:51 +00:00
|
|
|
if (!xpAccessible)
|
2012-04-09 14:45:47 +00:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2011-04-09 23:38:06 +00:00
|
|
|
// MSAA only has 31 states and the lowest 31 bits of our state bit mask
|
|
|
|
// are the same states as MSAA.
|
|
|
|
// Note: we map the following Gecko states to different MSAA states:
|
|
|
|
// REQUIRED -> ALERT_LOW
|
|
|
|
// ALERT -> ALERT_MEDIUM
|
|
|
|
// INVALID -> ALERT_HIGH
|
|
|
|
// CHECKABLE -> MARQUEED
|
|
|
|
|
|
|
|
PRUint32 msaaState = 0;
|
|
|
|
nsAccUtils::To32States(xpAccessible->State(), &msaaState, nsnull);
|
|
|
|
pvarState->lVal = msaaState;
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accHelp(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ BSTR __RPC_FAR *pszHelp)
|
|
|
|
{
|
2010-01-12 19:57:00 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
*pszHelp = NULL;
|
|
|
|
return S_FALSE;
|
2010-01-12 19:57:00 +00:00
|
|
|
|
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(),
|
|
|
|
GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accHelpTopic(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [out] */ BSTR __RPC_FAR *pszHelpFile,
|
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ long __RPC_FAR *pidTopic)
|
|
|
|
{
|
2010-01-12 19:57:00 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
*pszHelpFile = NULL;
|
|
|
|
*pidTopic = 0;
|
2010-01-12 19:57:00 +00:00
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(),
|
|
|
|
GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accKeyboardShortcut(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2011-06-28 23:27:03 +00:00
|
|
|
if (!pszKeyboardShortcut)
|
|
|
|
return E_INVALIDARG;
|
2003-04-01 20:02:51 +00:00
|
|
|
*pszKeyboardShortcut = NULL;
|
2011-07-19 08:30:24 +00:00
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2011-07-19 08:30:24 +00:00
|
|
|
nsAccessible* acc = GetXPAccessibleFor(varChild);
|
2012-04-09 14:45:47 +00:00
|
|
|
if (!acc)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (acc->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2008-03-16 01:17:38 +00:00
|
|
|
|
2011-07-19 08:30:24 +00:00
|
|
|
KeyBinding keyBinding = acc->AccessKey();
|
|
|
|
if (keyBinding.IsEmpty())
|
|
|
|
keyBinding = acc->KeyboardShortcut();
|
|
|
|
|
2011-06-28 23:27:03 +00:00
|
|
|
nsAutoString shortcut;
|
2011-07-19 08:30:24 +00:00
|
|
|
keyBinding.ToString(shortcut);
|
2011-06-28 23:27:03 +00:00
|
|
|
|
|
|
|
*pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(),
|
|
|
|
shortcut.Length());
|
|
|
|
return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY;
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2008-03-16 01:17:38 +00:00
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accFocus(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarChild)
|
|
|
|
{
|
2005-02-15 14:21:01 +00:00
|
|
|
// VT_EMPTY: None. This object does not have the keyboard focus itself
|
|
|
|
// and does not contain a child that has the keyboard focus.
|
|
|
|
// VT_I4: lVal is CHILDID_SELF. The object itself has the keyboard focus.
|
|
|
|
// VT_I4: lVal contains the child ID of the child element with the keyboard focus.
|
|
|
|
// VT_DISPATCH: pdispVal member is the address of the IDispatch interface
|
|
|
|
// for the child object with the keyboard focus.
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2010-06-11 08:23:18 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2004-07-01 20:43:03 +00:00
|
|
|
VariantInit(pvarChild);
|
2005-02-15 14:21:01 +00:00
|
|
|
|
|
|
|
// Return the current IAccessible child that has focus
|
2011-07-15 22:58:49 +00:00
|
|
|
nsAccessible* focusedAccessible = FocusedChild();
|
2005-02-18 14:36:28 +00:00
|
|
|
if (focusedAccessible == this) {
|
|
|
|
pvarChild->vt = VT_I4;
|
|
|
|
pvarChild->lVal = CHILDID_SELF;
|
|
|
|
}
|
|
|
|
else if (focusedAccessible) {
|
|
|
|
pvarChild->vt = VT_DISPATCH;
|
|
|
|
pvarChild->pdispVal = NativeAccessible(focusedAccessible);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pvarChild->vt = VT_EMPTY; // No focus or focus is not a child
|
2005-02-08 15:29:29 +00:00
|
|
|
}
|
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2004-07-01 20:43:03 +00:00
|
|
|
return S_OK;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2007-01-20 12:43:08 +00:00
|
|
|
// This helper class implements IEnumVARIANT for a nsIArray containing nsIAccessible objects.
|
|
|
|
|
|
|
|
class AccessibleEnumerator : public IEnumVARIANT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
AccessibleEnumerator(nsIArray* aArray) : mArray(aArray), mCurIndex(0) { }
|
|
|
|
AccessibleEnumerator(const AccessibleEnumerator& toCopy) :
|
|
|
|
mArray(toCopy.mArray), mCurIndex(toCopy.mCurIndex) { }
|
|
|
|
~AccessibleEnumerator() { }
|
|
|
|
|
|
|
|
// IUnknown
|
|
|
|
STDMETHODIMP QueryInterface(REFIID iid, void ** ppvObject);
|
|
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
|
|
|
|
// IEnumVARIANT
|
|
|
|
STDMETHODIMP Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched);
|
|
|
|
STDMETHODIMP Skip(unsigned long celt);
|
|
|
|
STDMETHODIMP Reset()
|
|
|
|
{
|
|
|
|
mCurIndex = 0;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
STDMETHODIMP Clone(IEnumVARIANT FAR* FAR* ppenum);
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIArray> mArray;
|
|
|
|
PRUint32 mCurIndex;
|
|
|
|
nsAutoRefCnt mRefCnt;
|
|
|
|
};
|
|
|
|
|
|
|
|
HRESULT
|
|
|
|
AccessibleEnumerator::QueryInterface(REFIID iid, void ** ppvObject)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2007-01-20 12:43:08 +00:00
|
|
|
if (iid == IID_IEnumVARIANT) {
|
|
|
|
*ppvObject = static_cast<IEnumVARIANT*>(this);
|
|
|
|
AddRef();
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
if (iid == IID_IUnknown) {
|
|
|
|
*ppvObject = static_cast<IUnknown*>(this);
|
|
|
|
AddRef();
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppvObject = NULL;
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2007-01-20 12:43:08 +00:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
|
|
AccessibleEnumerator::AddRef(void)
|
|
|
|
{
|
|
|
|
return ++mRefCnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
|
|
AccessibleEnumerator::Release(void)
|
|
|
|
{
|
|
|
|
ULONG r = --mRefCnt;
|
|
|
|
if (r == 0)
|
|
|
|
delete this;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
|
|
|
AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2007-01-20 12:43:08 +00:00
|
|
|
PRUint32 length = 0;
|
|
|
|
mArray->GetLength(&length);
|
|
|
|
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
// Can't get more elements than there are...
|
|
|
|
if (celt > length - mCurIndex) {
|
|
|
|
hr = S_FALSE;
|
|
|
|
celt = length - mCurIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (PRUint32 i = 0; i < celt; ++i, ++mCurIndex) {
|
|
|
|
// Copy the elements of the array into rgvar
|
|
|
|
nsCOMPtr<nsIAccessible> accel(do_QueryElementAt(mArray, mCurIndex));
|
|
|
|
NS_ASSERTION(accel, "Invalid pointer in mArray");
|
|
|
|
|
|
|
|
if (accel) {
|
|
|
|
rgvar[i].vt = VT_DISPATCH;
|
|
|
|
rgvar[i].pdispVal = nsAccessibleWrap::NativeAccessible(accel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pceltFetched)
|
|
|
|
*pceltFetched = celt;
|
|
|
|
|
|
|
|
return hr;
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
|
|
|
|
return S_OK;
|
2007-01-20 12:43:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
|
|
|
AccessibleEnumerator::Clone(IEnumVARIANT FAR* FAR* ppenum)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2007-01-20 12:43:08 +00:00
|
|
|
*ppenum = new AccessibleEnumerator(*this);
|
|
|
|
if (!*ppenum)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
NS_ADDREF(*ppenum);
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2007-01-20 12:43:08 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
|
|
|
AccessibleEnumerator::Skip(unsigned long celt)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2007-01-20 12:43:08 +00:00
|
|
|
PRUint32 length = 0;
|
|
|
|
mArray->GetLength(&length);
|
|
|
|
// Check if we can skip the requested number of elements
|
|
|
|
if (celt > length - mCurIndex) {
|
|
|
|
mCurIndex = length;
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
mCurIndex += celt;
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2007-01-20 12:43:08 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
/**
|
|
|
|
* This method is called when a client wants to know which children of a node
|
2007-01-20 12:43:08 +00:00
|
|
|
* are selected. Note that this method can only find selected children for
|
2010-09-02 00:46:59 +00:00
|
|
|
* nsIAccessible object which implement SelectAccessible.
|
2003-04-01 20:02:51 +00:00
|
|
|
*
|
|
|
|
* The VARIANT return value arguement is expected to either contain a single IAccessible
|
|
|
|
* or an IEnumVARIANT of IAccessibles. We return the IEnumVARIANT regardless of the number
|
2007-01-20 12:43:08 +00:00
|
|
|
* of children selected, unless there are none selected in which case we return an empty
|
2003-04-01 20:02:51 +00:00
|
|
|
* VARIANT.
|
|
|
|
*
|
2007-01-20 12:43:08 +00:00
|
|
|
* We get the selected options from the select's accessible object and wrap
|
|
|
|
* those in an AccessibleEnumerator which we then put in the return VARIANT.
|
2003-04-01 20:02:51 +00:00
|
|
|
*
|
|
|
|
* returns a VT_EMPTY VARIANT if:
|
2007-01-20 12:43:08 +00:00
|
|
|
* - there are no selected children for this object
|
|
|
|
* - the object is not the type that can have children selected
|
2003-04-01 20:02:51 +00:00
|
|
|
*/
|
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
VariantInit(pvarChildren);
|
|
|
|
pvarChildren->vt = VT_EMPTY;
|
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2010-09-02 00:46:59 +00:00
|
|
|
if (IsSelect()) {
|
|
|
|
nsCOMPtr<nsIArray> selectedItems = SelectedItems();
|
|
|
|
if (selectedItems) {
|
2007-01-20 12:43:08 +00:00
|
|
|
// 1) Create and initialize the enumeration
|
2010-09-02 00:46:59 +00:00
|
|
|
nsRefPtr<AccessibleEnumerator> pEnum =
|
|
|
|
new AccessibleEnumerator(selectedItems);
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2007-01-20 12:43:08 +00:00
|
|
|
// 2) Put the enumerator in the VARIANT
|
|
|
|
if (!pEnum)
|
|
|
|
return E_OUTOFMEMORY;
|
2003-04-01 20:02:51 +00:00
|
|
|
pvarChildren->vt = VT_UNKNOWN; // this must be VT_UNKNOWN for an IEnumVARIANT
|
2007-01-20 12:43:08 +00:00
|
|
|
NS_ADDREF(pvarChildren->punkVal = pEnum);
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
}
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::get_accDefaultAction(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
*pszDefaultAction = NULL;
|
2012-04-09 14:45:47 +00:00
|
|
|
|
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
|
|
|
if (!xpAccessible)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
nsAutoString defaultAction;
|
|
|
|
if (NS_FAILED(xpAccessible->GetActionName(0, defaultAction)))
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
*pszDefaultAction = ::SysAllocStringLen(defaultAction.get(),
|
|
|
|
defaultAction.Length());
|
|
|
|
return *pszDefaultAction ? S_OK : E_OUTOFMEMORY;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2008-03-16 01:17:38 +00:00
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::accSelect(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [in] */ long flagsSelect,
|
|
|
|
/* [optional][in] */ VARIANT varChild)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
// currently only handle focus and selection
|
2012-04-09 14:45:47 +00:00
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
|
|
|
if (!xpAccessible)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
if (flagsSelect & (SELFLAG_TAKEFOCUS|SELFLAG_TAKESELECTION|SELFLAG_REMOVESELECTION))
|
|
|
|
{
|
|
|
|
if (flagsSelect & SELFLAG_TAKEFOCUS)
|
2003-07-31 08:09:39 +00:00
|
|
|
xpAccessible->TakeFocus();
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
if (flagsSelect & SELFLAG_TAKESELECTION)
|
2003-07-31 08:09:39 +00:00
|
|
|
xpAccessible->TakeSelection();
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2006-06-15 18:29:44 +00:00
|
|
|
if (flagsSelect & SELFLAG_ADDSELECTION)
|
2011-10-17 14:59:28 +00:00
|
|
|
xpAccessible->SetSelected(true);
|
2006-06-15 18:29:44 +00:00
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
if (flagsSelect & SELFLAG_REMOVESELECTION)
|
2011-10-17 14:59:28 +00:00
|
|
|
xpAccessible->SetSelected(false);
|
2006-06-15 18:29:44 +00:00
|
|
|
|
|
|
|
if (flagsSelect & SELFLAG_EXTENDSELECTION)
|
|
|
|
xpAccessible->ExtendSelection();
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::accLocation(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [out] */ long __RPC_FAR *pxLeft,
|
|
|
|
/* [out] */ long __RPC_FAR *pyTop,
|
|
|
|
/* [out] */ long __RPC_FAR *pcxWidth,
|
|
|
|
/* [out] */ long __RPC_FAR *pcyHeight,
|
|
|
|
/* [optional][in] */ VARIANT varChild)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
|
|
|
if (!xpAccessible)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
PRInt32 x, y, width, height;
|
|
|
|
if (NS_FAILED(xpAccessible->GetBounds(&x, &y, &width, &height)))
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
*pxLeft = x;
|
|
|
|
*pyTop = y;
|
|
|
|
*pcxWidth = width;
|
|
|
|
*pcyHeight = height;
|
|
|
|
return S_OK;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::accNavigate(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [in] */ long navDir,
|
|
|
|
/* [optional][in] */ VARIANT varStart,
|
|
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2011-08-11 20:05:35 +00:00
|
|
|
if (!pvarEndUpAt)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2011-09-05 16:49:28 +00:00
|
|
|
nsAccessible* accessible = GetXPAccessibleFor(varStart);
|
2012-04-09 14:45:47 +00:00
|
|
|
if (!accessible)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (accessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
VariantInit(pvarEndUpAt);
|
2010-05-17 13:43:42 +00:00
|
|
|
|
2011-09-05 16:49:28 +00:00
|
|
|
nsAccessible* navAccessible = nsnull;
|
2005-06-24 16:29:15 +00:00
|
|
|
PRUint32 xpRelation = 0;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
switch(navDir) {
|
|
|
|
case NAVDIR_FIRSTCHILD:
|
2011-09-05 16:49:28 +00:00
|
|
|
if (!nsAccUtils::MustPrune(accessible))
|
|
|
|
navAccessible = accessible->FirstChild();
|
2003-04-01 20:02:51 +00:00
|
|
|
break;
|
|
|
|
case NAVDIR_LASTCHILD:
|
2011-09-05 16:49:28 +00:00
|
|
|
if (!nsAccUtils::MustPrune(accessible))
|
|
|
|
navAccessible = accessible->LastChild();
|
2003-04-01 20:02:51 +00:00
|
|
|
break;
|
|
|
|
case NAVDIR_NEXT:
|
2011-09-05 16:49:28 +00:00
|
|
|
navAccessible = accessible->NextSibling();
|
2003-04-01 20:02:51 +00:00
|
|
|
break;
|
|
|
|
case NAVDIR_PREVIOUS:
|
2011-09-05 16:49:28 +00:00
|
|
|
navAccessible = accessible->PrevSibling();
|
2003-04-01 20:02:51 +00:00
|
|
|
break;
|
2011-09-05 16:49:28 +00:00
|
|
|
case NAVDIR_DOWN:
|
|
|
|
case NAVDIR_LEFT:
|
2003-04-01 20:02:51 +00:00
|
|
|
case NAVDIR_RIGHT:
|
|
|
|
case NAVDIR_UP:
|
2011-09-05 16:49:28 +00:00
|
|
|
return E_NOTIMPL;
|
2007-05-20 02:41:33 +00:00
|
|
|
|
2005-06-24 16:29:15 +00:00
|
|
|
// MSAA relationship extensions to accNavigate
|
2007-05-20 02:41:33 +00:00
|
|
|
case NAVRELATION_CONTROLLED_BY:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_CONTROLLED_BY;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_CONTROLLER_FOR:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_CONTROLLER_FOR;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_LABEL_FOR:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_LABEL_FOR;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_LABELLED_BY:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_LABELLED_BY;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_MEMBER_OF:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_MEMBER_OF;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_NODE_CHILD_OF:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_NODE_CHILD_OF;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_FLOWS_TO:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_FLOWS_TO;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_FLOWS_FROM:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_FLOWS_FROM;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_SUBWINDOW_OF:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_SUBWINDOW_OF;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_EMBEDS:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_EMBEDS;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_EMBEDDED_BY:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_EMBEDDED_BY;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_POPUP_FOR:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_POPUP_FOR;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_PARENT_WINDOW_OF:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_DEFAULT_BUTTON:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_DEFAULT_BUTTON;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_DESCRIBED_BY:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_DESCRIBED_BY;
|
|
|
|
break;
|
|
|
|
case NAVRELATION_DESCRIPTION_FOR:
|
|
|
|
xpRelation = nsIAccessibleRelation::RELATION_DESCRIPTION_FOR;
|
|
|
|
break;
|
2011-09-05 16:49:28 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
return E_INVALIDARG;
|
2005-06-24 16:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pvarEndUpAt->vt = VT_EMPTY;
|
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
if (xpRelation) {
|
|
|
|
Relation rel = RelationByType(xpRelation);
|
2011-09-05 16:49:28 +00:00
|
|
|
navAccessible = rel.Next();
|
2011-08-10 01:44:00 +00:00
|
|
|
}
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2011-09-05 16:49:28 +00:00
|
|
|
if (navAccessible) {
|
|
|
|
pvarEndUpAt->pdispVal = NativeAccessible(navAccessible);
|
2003-04-01 20:02:51 +00:00
|
|
|
pvarEndUpAt->vt = VT_DISPATCH;
|
2011-08-10 01:44:00 +00:00
|
|
|
return S_OK;
|
2006-02-28 14:35:50 +00:00
|
|
|
}
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::accHitTest(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [in] */ long xLeft,
|
|
|
|
/* [in] */ long yTop,
|
|
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarChild)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2003-04-01 20:02:51 +00:00
|
|
|
VariantInit(pvarChild);
|
2012-04-09 14:45:47 +00:00
|
|
|
|
2011-06-13 22:20:54 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2011-06-13 22:20:54 +00:00
|
|
|
nsAccessible* accessible = ChildAtPoint(xLeft, yTop, eDirectChild);
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
// if we got a child
|
2011-06-13 22:20:54 +00:00
|
|
|
if (accessible) {
|
2003-04-01 20:02:51 +00:00
|
|
|
// if the child is us
|
2011-06-13 22:20:54 +00:00
|
|
|
if (accessible == this) {
|
2003-04-01 20:02:51 +00:00
|
|
|
pvarChild->vt = VT_I4;
|
|
|
|
pvarChild->lVal = CHILDID_SELF;
|
|
|
|
} else { // its not create an Accessible for it.
|
|
|
|
pvarChild->vt = VT_DISPATCH;
|
2011-06-13 22:20:54 +00:00
|
|
|
pvarChild->pdispVal = NativeAccessible(accessible);
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
} else {
|
2003-04-15 08:45:55 +00:00
|
|
|
// no child at that point
|
|
|
|
pvarChild->vt = VT_EMPTY;
|
2007-09-19 03:02:09 +00:00
|
|
|
return S_FALSE;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::accDoDefaultAction(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
nsAccessible* xpAccessible = GetXPAccessibleFor(varChild);
|
|
|
|
if (!xpAccessible)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (xpAccessible->IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
|
|
|
return GetHRESULT(xpAccessible->DoAction(0));
|
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2012-04-09 14:45:47 +00:00
|
|
|
return E_FAIL;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::put_accName(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [in] */ BSTR szName)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP nsAccessibleWrap::put_accValue(
|
2003-04-01 20:02:51 +00:00
|
|
|
/* [optional][in] */ VARIANT varChild,
|
|
|
|
/* [in] */ BSTR szValue)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
2008-07-08 14:23:18 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccessibleWrap. IAccessible2
|
2007-03-09 13:51:47 +00:00
|
|
|
|
|
|
|
STDMETHODIMP
|
2007-05-24 13:26:54 +00:00
|
|
|
nsAccessibleWrap::get_nRelations(long *aNRelations)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2011-08-10 01:44:00 +00:00
|
|
|
if (!aNRelations)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
*aNRelations = 0;
|
2007-05-24 13:26:54 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
for (PRUint32 relType = nsIAccessibleRelation::RELATION_FIRST;
|
|
|
|
relType <= nsIAccessibleRelation::RELATION_LAST; relType++) {
|
|
|
|
Relation rel = RelationByType(relType);
|
|
|
|
if (rel.Next())
|
|
|
|
(*aNRelations)++;
|
|
|
|
}
|
|
|
|
return S_OK;
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2008-03-30 03:24:02 +00:00
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2007-05-24 13:26:54 +00:00
|
|
|
nsAccessibleWrap::get_relation(long aRelationIndex,
|
|
|
|
IAccessibleRelation **aRelation)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2011-08-10 01:44:00 +00:00
|
|
|
if (!aRelation)
|
|
|
|
return E_INVALIDARG;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
*aRelation = NULL;
|
2007-05-24 13:26:54 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2007-05-24 13:26:54 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
PRUint32 relIdx = 0;
|
|
|
|
for (PRUint32 relType = nsIAccessibleRelation::RELATION_FIRST;
|
|
|
|
relType <= nsIAccessibleRelation::RELATION_LAST; relType++) {
|
|
|
|
Relation rel = RelationByType(relType);
|
|
|
|
nsRefPtr<ia2AccessibleRelation> ia2Relation =
|
|
|
|
new ia2AccessibleRelation(relType, &rel);
|
|
|
|
if (ia2Relation->HasTargets()) {
|
|
|
|
if (relIdx == aRelationIndex) {
|
|
|
|
ia2Relation.forget(aRelation);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2007-05-24 13:26:54 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
relIdx++;
|
|
|
|
}
|
|
|
|
}
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
return E_INVALIDARG;
|
2008-03-30 03:24:02 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2007-05-24 13:26:54 +00:00
|
|
|
nsAccessibleWrap::get_relations(long aMaxRelations,
|
|
|
|
IAccessibleRelation **aRelation,
|
|
|
|
long *aNRelations)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2011-08-10 01:44:00 +00:00
|
|
|
if (!aRelation || !aNRelations)
|
|
|
|
return E_INVALIDARG;
|
2007-05-24 13:26:54 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
*aNRelations = 0;
|
2007-05-24 13:26:54 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2007-05-24 13:26:54 +00:00
|
|
|
|
2011-08-10 01:44:00 +00:00
|
|
|
for (PRUint32 relType = nsIAccessibleRelation::RELATION_FIRST;
|
|
|
|
relType <= nsIAccessibleRelation::RELATION_LAST &&
|
|
|
|
*aNRelations < aMaxRelations; relType++) {
|
|
|
|
Relation rel = RelationByType(relType);
|
|
|
|
nsRefPtr<ia2AccessibleRelation> ia2Rel =
|
|
|
|
new ia2AccessibleRelation(relType, &rel);
|
|
|
|
if (ia2Rel->HasTargets()) {
|
|
|
|
ia2Rel.forget(aRelation + (*aNRelations));
|
|
|
|
(*aNRelations)++;
|
2007-05-24 13:26:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return S_OK;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-30 03:24:02 +00:00
|
|
|
nsAccessibleWrap::role(long *aRole)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2008-03-30 03:24:02 +00:00
|
|
|
*aRole = 0;
|
|
|
|
|
2010-09-14 23:22:09 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2010-09-14 23:22:09 +00:00
|
|
|
|
2012-04-26 18:25:33 +00:00
|
|
|
#define ROLE(_geckoRole, stringRole, atkRole, macRole, msaaRole, ia2Role) \
|
|
|
|
case roles::_geckoRole: \
|
|
|
|
*aRole = ia2Role; \
|
|
|
|
break;
|
|
|
|
|
|
|
|
a11y::role geckoRole = Role();
|
|
|
|
switch (geckoRole) {
|
|
|
|
#include "RoleMap.h"
|
|
|
|
default:
|
|
|
|
MOZ_NOT_REACHED("Unknown role.");
|
|
|
|
};
|
2007-03-10 03:00:08 +00:00
|
|
|
|
2012-04-26 18:25:33 +00:00
|
|
|
#undef ROLE
|
2009-08-20 06:45:19 +00:00
|
|
|
|
|
|
|
// Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call
|
|
|
|
// the IA2 role a ROLE_OUTLINEITEM.
|
2012-04-26 18:25:33 +00:00
|
|
|
if (geckoRole == roles::ROW) {
|
2011-07-23 08:38:33 +00:00
|
|
|
nsAccessible* xpParent = Parent();
|
2012-01-12 03:07:35 +00:00
|
|
|
if (xpParent && xpParent->Role() == roles::TREE_TABLE)
|
2009-08-20 06:45:19 +00:00
|
|
|
*aRole = ROLE_SYSTEM_OUTLINEITEM;
|
|
|
|
}
|
|
|
|
|
2007-03-10 03:00:08 +00:00
|
|
|
return S_OK;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2007-04-12 16:54:09 +00:00
|
|
|
nsAccessibleWrap::scrollTo(enum IA2ScrollType aScrollType)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2012-04-10 00:39:00 +00:00
|
|
|
nsCoreUtils::ScrollTo(mDoc->PresShell(), mContent, aScrollType);
|
2012-02-07 13:18:33 +00:00
|
|
|
return S_OK;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
2007-04-08 03:58:08 +00:00
|
|
|
STDMETHODIMP
|
2007-09-25 05:48:51 +00:00
|
|
|
nsAccessibleWrap::scrollToPoint(enum IA2CoordinateType aCoordType,
|
|
|
|
long aX, long aY)
|
2007-04-08 03:58:08 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2007-09-25 05:48:51 +00:00
|
|
|
PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
|
|
|
|
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
|
|
|
|
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
|
|
|
|
|
2008-03-30 03:24:02 +00:00
|
|
|
nsresult rv = ScrollToPoint(geckoCoordType, aX, aY);
|
|
|
|
return GetHRESULT(rv);
|
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2008-03-30 03:24:02 +00:00
|
|
|
return E_FAIL;
|
2007-04-08 03:58:08 +00:00
|
|
|
}
|
|
|
|
|
2007-03-09 13:51:47 +00:00
|
|
|
STDMETHODIMP
|
2007-03-27 12:17:11 +00:00
|
|
|
nsAccessibleWrap::get_groupPosition(long *aGroupLevel,
|
|
|
|
long *aSimilarItemsInGroup,
|
|
|
|
long *aPositionInGroup)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2007-03-27 12:17:11 +00:00
|
|
|
PRInt32 groupLevel = 0;
|
|
|
|
PRInt32 similarItemsInGroup = 0;
|
|
|
|
PRInt32 positionInGroup = 0;
|
2010-01-06 10:36:50 +00:00
|
|
|
|
2007-03-27 12:17:11 +00:00
|
|
|
nsresult rv = GroupPosition(&groupLevel, &similarItemsInGroup,
|
|
|
|
&positionInGroup);
|
2010-01-06 10:36:50 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return GetHRESULT(rv);
|
|
|
|
|
|
|
|
// Group information for accessibles having level only (like html headings
|
|
|
|
// elements) isn't exposed by this method. AT should look for 'level' object
|
|
|
|
// attribute.
|
|
|
|
if (!similarItemsInGroup && !positionInGroup)
|
|
|
|
return S_FALSE;
|
2007-03-27 12:17:11 +00:00
|
|
|
|
2008-03-30 03:24:02 +00:00
|
|
|
*aGroupLevel = groupLevel;
|
|
|
|
*aSimilarItemsInGroup = similarItemsInGroup;
|
|
|
|
*aPositionInGroup = positionInGroup;
|
|
|
|
|
|
|
|
return S_OK;
|
2007-03-27 12:17:11 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2007-03-27 12:17:11 +00:00
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2007-03-18 15:54:48 +00:00
|
|
|
nsAccessibleWrap::get_states(AccessibleStates *aStates)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates = 0;
|
|
|
|
|
|
|
|
// XXX: bug 344674 should come with better approach that we have here.
|
|
|
|
|
2011-04-09 23:38:06 +00:00
|
|
|
PRUint64 state = State();
|
2007-03-18 15:54:48 +00:00
|
|
|
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::INVALID)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_INVALID_ENTRY;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::REQUIRED)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_REQUIRED;
|
|
|
|
|
|
|
|
// The following IA2 states are not supported by Gecko
|
|
|
|
// IA2_STATE_ARMED
|
2007-08-10 19:28:28 +00:00
|
|
|
// IA2_STATE_MANAGES_DESCENDANTS
|
2007-03-18 15:54:48 +00:00
|
|
|
// IA2_STATE_ICONIFIED
|
2007-08-10 19:28:28 +00:00
|
|
|
// IA2_STATE_INVALID // This is not a state, it is the absence of a state
|
2007-03-18 15:54:48 +00:00
|
|
|
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::ACTIVE)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_ACTIVE;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::DEFUNCT)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_DEFUNCT;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::EDITABLE)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_EDITABLE;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::HORIZONTAL)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_HORIZONTAL;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::MODAL)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_MODAL;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::MULTI_LINE)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_MULTI_LINE;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::OPAQUE1)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_OPAQUE;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::SELECTABLE_TEXT)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_SELECTABLE_TEXT;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::SINGLE_LINE)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_SINGLE_LINE;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::STALE)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_STALE;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::SUPPORTS_AUTOCOMPLETION)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::TRANSIENT)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_TRANSIENT;
|
2011-04-09 23:38:06 +00:00
|
|
|
if (state & states::VERTICAL)
|
2007-03-18 15:54:48 +00:00
|
|
|
*aStates |= IA2_STATE_VERTICAL;
|
|
|
|
|
|
|
|
return S_OK;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-16 01:17:38 +00:00
|
|
|
nsAccessibleWrap::get_extendedRole(BSTR *aExtendedRole)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-03-16 01:17:38 +00:00
|
|
|
__try {
|
|
|
|
*aExtendedRole = NULL;
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-16 01:17:38 +00:00
|
|
|
nsAccessibleWrap::get_localizedExtendedRole(BSTR *aLocalizedExtendedRole)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-03-16 01:17:38 +00:00
|
|
|
__try {
|
|
|
|
*aLocalizedExtendedRole = NULL;
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-16 01:17:38 +00:00
|
|
|
nsAccessibleWrap::get_nExtendedStates(long *aNExtendedStates)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-03-16 01:17:38 +00:00
|
|
|
__try {
|
|
|
|
*aNExtendedStates = 0;
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-16 01:17:38 +00:00
|
|
|
nsAccessibleWrap::get_extendedStates(long aMaxExtendedStates,
|
|
|
|
BSTR **aExtendedStates,
|
|
|
|
long *aNExtendedStates)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-03-16 01:17:38 +00:00
|
|
|
__try {
|
|
|
|
*aExtendedStates = NULL;
|
|
|
|
*aNExtendedStates = 0;
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-16 01:17:38 +00:00
|
|
|
nsAccessibleWrap::get_localizedExtendedStates(long aMaxLocalizedExtendedStates,
|
|
|
|
BSTR **aLocalizedExtendedStates,
|
|
|
|
long *aNLocalizedExtendedStates)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-03-16 01:17:38 +00:00
|
|
|
__try {
|
|
|
|
*aLocalizedExtendedStates = NULL;
|
|
|
|
*aNLocalizedExtendedStates = 0;
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
|
|
|
nsAccessibleWrap::get_uniqueID(long *uniqueID)
|
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2010-10-21 04:16:10 +00:00
|
|
|
*uniqueID = - reinterpret_cast<long>(UniqueID());
|
2008-03-30 03:24:02 +00:00
|
|
|
return S_OK;
|
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-30 03:24:02 +00:00
|
|
|
nsAccessibleWrap::get_windowHandle(HWND *aWindowHandle)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2008-03-30 03:24:02 +00:00
|
|
|
*aWindowHandle = 0;
|
|
|
|
|
2010-06-11 08:23:18 +00:00
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2011-02-22 13:54:56 +00:00
|
|
|
*aWindowHandle = GetHWNDFor(this);
|
2007-12-11 03:35:22 +00:00
|
|
|
return S_OK;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2008-03-30 03:24:02 +00:00
|
|
|
nsAccessibleWrap::get_indexInParent(long *aIndexInParent)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2011-06-13 09:08:40 +00:00
|
|
|
if (!aIndexInParent)
|
|
|
|
return E_INVALIDARG;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2011-06-13 09:08:40 +00:00
|
|
|
*aIndexInParent = -1;
|
|
|
|
if (IsDefunct())
|
2012-04-09 14:45:47 +00:00
|
|
|
return CO_E_OBJNOTCONNECTED;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
2011-06-13 09:08:40 +00:00
|
|
|
*aIndexInParent = IndexInParent();
|
|
|
|
if (*aIndexInParent == -1)
|
2008-03-30 03:24:02 +00:00
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
return S_OK;
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2007-03-09 13:51:47 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2007-12-01 17:31:06 +00:00
|
|
|
nsAccessibleWrap::get_locale(IA2Locale *aLocale)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2007-12-01 17:31:06 +00:00
|
|
|
// Language codes consist of a primary code and a possibly empty series of
|
|
|
|
// subcodes: language-code = primary-code ( "-" subcode )*
|
|
|
|
// Two-letter primary codes are reserved for [ISO639] language abbreviations.
|
|
|
|
// Any two-letter subcode is understood to be a [ISO3166] country code.
|
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2007-12-01 17:31:06 +00:00
|
|
|
nsAutoString lang;
|
2012-02-07 13:18:33 +00:00
|
|
|
Language(lang);
|
2007-12-01 17:31:06 +00:00
|
|
|
|
|
|
|
// If primary code consists from two letters then expose it as language.
|
|
|
|
PRInt32 offset = lang.FindChar('-', 0);
|
|
|
|
if (offset == -1) {
|
|
|
|
if (lang.Length() == 2) {
|
|
|
|
aLocale->language = ::SysAllocString(lang.get());
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
} else if (offset == 2) {
|
|
|
|
aLocale->language = ::SysAllocStringLen(lang.get(), 2);
|
|
|
|
|
|
|
|
// If the first subcode consists from two letters then expose it as
|
|
|
|
// country.
|
|
|
|
offset = lang.FindChar('-', 3);
|
|
|
|
if (offset == -1) {
|
|
|
|
if (lang.Length() == 5) {
|
|
|
|
aLocale->country = ::SysAllocString(lang.get() + 3);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
} else if (offset == 5) {
|
|
|
|
aLocale->country = ::SysAllocStringLen(lang.get() + 3, 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expose as a string if primary code or subcode cannot point to language or
|
|
|
|
// country abbreviations or if there are more than one subcode.
|
|
|
|
aLocale->variant = ::SysAllocString(lang.get());
|
|
|
|
return S_OK;
|
2008-03-30 03:24:02 +00:00
|
|
|
|
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
2007-04-20 04:48:04 +00:00
|
|
|
nsAccessibleWrap::get_attributes(BSTR *aAttributes)
|
2007-03-09 13:51:47 +00:00
|
|
|
{
|
2007-04-20 04:48:04 +00:00
|
|
|
// The format is name:value;name:value; with \ for escaping these
|
|
|
|
// characters ":;=,\".
|
2008-02-09 02:40:47 +00:00
|
|
|
__try {
|
2008-03-10 02:24:00 +00:00
|
|
|
*aAttributes = NULL;
|
|
|
|
|
2012-04-09 14:45:47 +00:00
|
|
|
if (IsDefunct())
|
|
|
|
return CO_E_OBJNOTCONNECTED;
|
|
|
|
|
2007-04-20 04:48:04 +00:00
|
|
|
nsCOMPtr<nsIPersistentProperties> attributes;
|
2008-03-30 03:24:02 +00:00
|
|
|
nsresult rv = GetAttributes(getter_AddRefs(attributes));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return GetHRESULT(rv);
|
2007-04-20 04:48:04 +00:00
|
|
|
|
2008-07-17 12:06:24 +00:00
|
|
|
return ConvertToIA2Attributes(attributes, aAttributes);
|
2008-03-07 00:33:47 +00:00
|
|
|
|
2008-02-09 02:40:47 +00:00
|
|
|
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
2008-03-30 03:24:02 +00:00
|
|
|
return E_FAIL;
|
2007-03-09 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
2010-01-08 06:50:38 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// IDispatch
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP
|
2010-01-08 06:50:38 +00:00
|
|
|
nsAccessibleWrap::GetTypeInfoCount(UINT *pctinfo)
|
2003-04-01 20:02:51 +00:00
|
|
|
{
|
2010-01-08 06:50:38 +00:00
|
|
|
*pctinfo = 1;
|
|
|
|
return S_OK;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2010-01-08 06:50:38 +00:00
|
|
|
STDMETHODIMP
|
|
|
|
nsAccessibleWrap::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
|
2003-04-01 20:02:51 +00:00
|
|
|
{
|
2010-01-08 06:50:38 +00:00
|
|
|
*ppTInfo = NULL;
|
|
|
|
|
|
|
|
if (iTInfo != 0)
|
2010-02-20 13:45:19 +00:00
|
|
|
return DISP_E_BADINDEX;
|
2010-01-08 06:50:38 +00:00
|
|
|
|
|
|
|
ITypeInfo * typeInfo = GetTI(lcid);
|
|
|
|
if (!typeInfo)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
typeInfo->AddRef();
|
|
|
|
*ppTInfo = typeInfo;
|
|
|
|
|
|
|
|
return S_OK;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 14:35:50 +00:00
|
|
|
STDMETHODIMP
|
2003-04-01 20:02:51 +00:00
|
|
|
nsAccessibleWrap::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames,
|
2010-01-08 06:50:38 +00:00
|
|
|
UINT cNames, LCID lcid, DISPID *rgDispId)
|
2003-04-01 20:02:51 +00:00
|
|
|
{
|
2010-01-08 06:50:38 +00:00
|
|
|
ITypeInfo *typeInfo = GetTI(lcid);
|
|
|
|
if (!typeInfo)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
HRESULT hr = DispGetIDsOfNames(typeInfo, rgszNames, cNames, rgDispId);
|
|
|
|
return hr;
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2010-01-08 06:50:38 +00:00
|
|
|
STDMETHODIMP
|
|
|
|
nsAccessibleWrap::Invoke(DISPID dispIdMember, REFIID riid,
|
|
|
|
LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
|
|
|
|
VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
|
|
|
|
UINT *puArgErr)
|
2003-04-01 20:02:51 +00:00
|
|
|
{
|
2010-01-08 06:50:38 +00:00
|
|
|
ITypeInfo *typeInfo = GetTI(lcid);
|
|
|
|
if (!typeInfo)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
return typeInfo->Invoke(static_cast<IAccessible*>(this), dispIdMember,
|
|
|
|
wFlags, pDispParams, pVarResult, pExcepInfo,
|
|
|
|
puArgErr);
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-08 06:50:38 +00:00
|
|
|
// nsIAccessible method
|
2003-04-01 20:02:51 +00:00
|
|
|
NS_IMETHODIMP nsAccessibleWrap::GetNativeInterface(void **aOutAccessible)
|
|
|
|
{
|
2007-07-08 07:08:04 +00:00
|
|
|
*aOutAccessible = static_cast<IAccessible*>(this);
|
2005-09-02 01:33:23 +00:00
|
|
|
NS_ADDREF_THIS();
|
2003-04-01 20:02:51 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-02-22 13:54:56 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2009-06-18 07:37:38 +00:00
|
|
|
// nsAccessible
|
2007-04-16 20:23:00 +00:00
|
|
|
|
2009-06-18 07:37:38 +00:00
|
|
|
nsresult
|
2010-08-25 02:08:28 +00:00
|
|
|
nsAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
|
2007-04-16 20:23:00 +00:00
|
|
|
{
|
2010-01-19 04:23:44 +00:00
|
|
|
nsresult rv = nsAccessible::HandleAccEvent(aEvent);
|
2007-04-16 20:23:00 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2008-06-16 06:16:18 +00:00
|
|
|
return FirePlatformEvent(aEvent);
|
|
|
|
}
|
|
|
|
|
2011-02-22 13:54:56 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccessibleWrap
|
|
|
|
|
2008-06-16 06:16:18 +00:00
|
|
|
nsresult
|
2010-08-25 02:08:28 +00:00
|
|
|
nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
|
2008-06-16 06:16:18 +00:00
|
|
|
{
|
2010-01-19 04:23:44 +00:00
|
|
|
PRUint32 eventType = aEvent->GetEventType();
|
2007-04-16 20:23:00 +00:00
|
|
|
|
|
|
|
NS_ENSURE_TRUE(eventType > 0 &&
|
|
|
|
eventType < nsIAccessibleEvent::EVENT_LAST_ENTRY,
|
|
|
|
NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
PRUint32 winLastEntry = gWinEventMap[nsIAccessibleEvent::EVENT_LAST_ENTRY];
|
|
|
|
NS_ASSERTION(winLastEntry == kEVENT_LAST_ENTRY,
|
|
|
|
"MSAA event map skewed");
|
|
|
|
|
|
|
|
PRUint32 winEvent = gWinEventMap[eventType];
|
|
|
|
if (!winEvent)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// Means we're not active.
|
2012-02-07 22:38:54 +00:00
|
|
|
NS_ENSURE_TRUE(!IsDefunct(), NS_ERROR_FAILURE);
|
2007-04-16 20:23:00 +00:00
|
|
|
|
2010-06-12 04:04:24 +00:00
|
|
|
nsAccessible *accessible = aEvent->GetAccessible();
|
2007-04-16 20:23:00 +00:00
|
|
|
if (!accessible)
|
|
|
|
return NS_OK;
|
|
|
|
|
2007-06-14 17:12:50 +00:00
|
|
|
if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED ||
|
|
|
|
eventType == nsIAccessibleEvent::EVENT_FOCUS) {
|
|
|
|
UpdateSystemCaret();
|
2007-05-07 18:55:17 +00:00
|
|
|
}
|
2010-10-21 04:16:10 +00:00
|
|
|
|
2007-05-07 18:59:08 +00:00
|
|
|
PRInt32 childID = GetChildIDFor(accessible); // get the id for the accessible
|
|
|
|
if (!childID)
|
|
|
|
return NS_OK; // Can't fire an event without a child ID
|
|
|
|
|
2010-10-21 04:16:10 +00:00
|
|
|
HWND hWnd = GetHWNDFor(accessible);
|
2007-06-30 02:49:32 +00:00
|
|
|
NS_ENSURE_TRUE(hWnd, NS_ERROR_FAILURE);
|
2007-04-16 20:23:00 +00:00
|
|
|
|
2010-10-21 04:16:10 +00:00
|
|
|
nsAutoString tag;
|
|
|
|
nsCAutoString id;
|
|
|
|
nsIContent* cnt = accessible->GetContent();
|
|
|
|
if (cnt) {
|
|
|
|
cnt->Tag()->ToString(tag);
|
|
|
|
nsIAtom* aid = cnt->GetID();
|
|
|
|
if (aid)
|
|
|
|
aid->ToUTF8String(id);
|
|
|
|
}
|
|
|
|
|
2012-05-07 23:49:41 +00:00
|
|
|
#ifdef DEBUG
|
2010-10-21 04:16:10 +00:00
|
|
|
printf("\n\nMSAA event: event: %d, target: %s@id='%s', childid: %d, hwnd: %d\n\n",
|
|
|
|
eventType, NS_ConvertUTF16toUTF8(tag).get(), id.get(),
|
|
|
|
childID, hWnd);
|
|
|
|
#endif
|
2007-04-16 20:23:00 +00:00
|
|
|
|
|
|
|
// Fire MSAA event for client area window.
|
2012-02-02 12:29:58 +00:00
|
|
|
::NotifyWinEvent(winEvent, hWnd, OBJID_CLIENT, childID);
|
2011-11-22 05:01:02 +00:00
|
|
|
|
|
|
|
// JAWS announces collapsed combobox navigation based on focus events.
|
2011-12-06 06:07:46 +00:00
|
|
|
if (Compatibility::IsJAWS()) {
|
|
|
|
if (eventType == nsIAccessibleEvent::EVENT_SELECTION &&
|
2012-01-12 03:07:35 +00:00
|
|
|
accessible->Role() == roles::COMBOBOX_OPTION) {
|
2012-02-02 12:29:58 +00:00
|
|
|
::NotifyWinEvent(EVENT_OBJECT_FOCUS, hWnd, OBJID_CLIENT, childID);
|
2011-12-06 06:07:46 +00:00
|
|
|
}
|
2011-11-22 05:01:02 +00:00
|
|
|
}
|
2011-12-06 06:07:46 +00:00
|
|
|
|
2007-04-16 20:23:00 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2006-02-28 14:35:50 +00:00
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
//------- Helper methods ---------
|
|
|
|
|
2010-10-21 04:16:10 +00:00
|
|
|
PRInt32 nsAccessibleWrap::GetChildIDFor(nsAccessible* aAccessible)
|
2007-04-16 20:23:00 +00:00
|
|
|
{
|
|
|
|
// A child ID of the window is required, when we use NotifyWinEvent,
|
|
|
|
// so that the 3rd party application can call back and get the IAccessible
|
2010-05-13 12:19:50 +00:00
|
|
|
// the event occurred on.
|
2007-04-16 20:23:00 +00:00
|
|
|
|
|
|
|
// Yes, this means we're only compatibible with 32 bit
|
|
|
|
// MSAA is only available for 32 bit windows, so it's okay
|
2010-10-21 04:16:10 +00:00
|
|
|
// XXX: bug 606080
|
|
|
|
return aAccessible ? - NS_PTR_TO_INT32(aAccessible->UniqueID()) : 0;
|
2007-04-16 20:23:00 +00:00
|
|
|
}
|
|
|
|
|
2007-06-30 02:49:32 +00:00
|
|
|
HWND
|
2010-06-12 04:04:50 +00:00
|
|
|
nsAccessibleWrap::GetHWNDFor(nsAccessible *aAccessible)
|
2007-06-30 02:49:32 +00:00
|
|
|
{
|
2011-02-22 13:54:56 +00:00
|
|
|
if (aAccessible) {
|
2011-11-09 22:52:00 +00:00
|
|
|
nsDocAccessible* document = aAccessible->Document();
|
2012-02-07 22:38:54 +00:00
|
|
|
if(!document)
|
|
|
|
return nsnull;
|
|
|
|
|
2011-02-22 13:54:56 +00:00
|
|
|
// Popup lives in own windows, use its HWND until the popup window is
|
|
|
|
// hidden to make old JAWS versions work with collapsed comboboxes (see
|
|
|
|
// discussion in bug 379678).
|
|
|
|
nsIFrame* frame = aAccessible->GetFrame();
|
|
|
|
if (frame) {
|
|
|
|
nsIWidget* widget = frame->GetNearestWidget();
|
2011-10-11 00:06:10 +00:00
|
|
|
if (widget) {
|
|
|
|
bool isVisible = false;
|
|
|
|
widget->IsVisible(isVisible);
|
|
|
|
if (isVisible) {
|
2012-04-05 03:11:39 +00:00
|
|
|
nsIPresShell* shell = document->PresShell();
|
2011-10-11 00:06:10 +00:00
|
|
|
nsIViewManager* vm = shell->GetViewManager();
|
|
|
|
if (vm) {
|
|
|
|
nsCOMPtr<nsIWidget> rootWidget;
|
|
|
|
vm->GetRootWidget(getter_AddRefs(rootWidget));
|
|
|
|
// Make sure the accessible belongs to popup. If not then use
|
|
|
|
// document HWND (which might be different from root widget in the
|
|
|
|
// case of window emulation).
|
|
|
|
if (rootWidget != widget)
|
|
|
|
return static_cast<HWND>(widget->GetNativeData(NS_NATIVE_WINDOW));
|
|
|
|
}
|
2011-02-22 13:54:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-06-30 02:49:32 +00:00
|
|
|
|
2012-02-07 22:38:54 +00:00
|
|
|
return static_cast<HWND>(document->GetNativeWindow());
|
2011-02-22 13:54:56 +00:00
|
|
|
}
|
|
|
|
return nsnull;
|
2007-06-30 02:49:32 +00:00
|
|
|
}
|
|
|
|
|
2008-07-17 12:06:24 +00:00
|
|
|
HRESULT
|
|
|
|
nsAccessibleWrap::ConvertToIA2Attributes(nsIPersistentProperties *aAttributes,
|
|
|
|
BSTR *aIA2Attributes)
|
|
|
|
{
|
|
|
|
*aIA2Attributes = NULL;
|
|
|
|
|
|
|
|
// The format is name:value;name:value; with \ for escaping these
|
|
|
|
// characters ":;=,\".
|
|
|
|
|
|
|
|
if (!aAttributes)
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> propEnum;
|
|
|
|
aAttributes->Enumerate(getter_AddRefs(propEnum));
|
|
|
|
if (!propEnum)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
nsAutoString strAttrs;
|
|
|
|
|
|
|
|
const char kCharsToEscape[] = ":;=,\\";
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool hasMore = false;
|
2008-07-17 12:06:24 +00:00
|
|
|
while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
|
|
|
|
nsCOMPtr<nsISupports> propSupports;
|
|
|
|
propEnum->GetNext(getter_AddRefs(propSupports));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(propSupports));
|
|
|
|
if (!propElem)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
nsCAutoString name;
|
|
|
|
if (NS_FAILED(propElem->GetKey(name)))
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
PRUint32 offset = 0;
|
|
|
|
while ((offset = name.FindCharInSet(kCharsToEscape, offset)) != kNotFound) {
|
|
|
|
name.Insert('\\', offset);
|
|
|
|
offset += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
if (NS_FAILED(propElem->GetValue(value)))
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
offset = 0;
|
|
|
|
while ((offset = value.FindCharInSet(kCharsToEscape, offset)) != kNotFound) {
|
|
|
|
value.Insert('\\', offset);
|
|
|
|
offset += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
AppendUTF8toUTF16(name, strAttrs);
|
|
|
|
strAttrs.Append(':');
|
|
|
|
strAttrs.Append(value);
|
|
|
|
strAttrs.Append(';');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strAttrs.IsEmpty())
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
*aIA2Attributes = ::SysAllocStringLen(strAttrs.get(), strAttrs.Length());
|
|
|
|
return *aIA2Attributes ? S_OK : E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
2012-02-11 07:45:10 +00:00
|
|
|
IDispatch*
|
|
|
|
nsAccessibleWrap::NativeAccessible(nsIAccessible* aAccessible)
|
2003-04-01 20:02:51 +00:00
|
|
|
{
|
2012-02-11 07:45:10 +00:00
|
|
|
if (!aAccessible) {
|
|
|
|
NS_WARNING("Not passing in an aAccessible");
|
2007-05-18 03:00:21 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-02-11 07:45:10 +00:00
|
|
|
IAccessible* msaaAccessible = nsnull;
|
|
|
|
aAccessible->GetNativeInterface(reinterpret_cast<void**>(&msaaAccessible));
|
2007-07-08 07:08:04 +00:00
|
|
|
return static_cast<IDispatch*>(msaaAccessible);
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2010-05-17 13:43:42 +00:00
|
|
|
nsAccessible*
|
|
|
|
nsAccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild)
|
2003-04-01 20:02:51 +00:00
|
|
|
{
|
2010-09-09 14:44:56 +00:00
|
|
|
if (aVarChild.vt != VT_I4)
|
2010-05-17 13:43:42 +00:00
|
|
|
return nsnull;
|
2003-04-01 20:02:51 +00:00
|
|
|
|
|
|
|
// if its us real easy - this seems to always be the case
|
2010-05-17 13:43:42 +00:00
|
|
|
if (aVarChild.lVal == CHILDID_SELF)
|
|
|
|
return this;
|
|
|
|
|
|
|
|
if (nsAccUtils::MustPrune(this))
|
|
|
|
return nsnull;
|
|
|
|
|
2011-05-20 05:17:47 +00:00
|
|
|
// If lVal negative then it is treated as child ID and we should look for
|
|
|
|
// accessible through whole accessible subtree including subdocuments.
|
|
|
|
// Otherwise we treat lVal as index in parent.
|
|
|
|
|
|
|
|
if (aVarChild.lVal < 0) {
|
|
|
|
// Convert child ID to unique ID.
|
|
|
|
void* uniqueID = reinterpret_cast<void*>(-aVarChild.lVal);
|
|
|
|
|
|
|
|
// Document.
|
|
|
|
if (IsDoc())
|
|
|
|
return AsDoc()->GetAccessibleByUniqueIDInSubtree(uniqueID);
|
|
|
|
|
|
|
|
// ARIA document.
|
2012-01-12 03:07:35 +00:00
|
|
|
if (ARIARole() == roles::DOCUMENT) {
|
2011-11-09 22:52:00 +00:00
|
|
|
nsDocAccessible* document = Document();
|
2011-05-20 05:17:47 +00:00
|
|
|
nsAccessible* child =
|
|
|
|
document->GetAccessibleByUniqueIDInSubtree(uniqueID);
|
|
|
|
|
|
|
|
// Check whether the accessible for the given ID is a child of ARIA
|
|
|
|
// document.
|
2011-07-23 08:38:33 +00:00
|
|
|
nsAccessible* parent = child ? child->Parent() : nsnull;
|
2011-05-20 05:17:47 +00:00
|
|
|
while (parent && parent != document) {
|
|
|
|
if (parent == this)
|
|
|
|
return child;
|
|
|
|
|
2011-07-23 08:38:33 +00:00
|
|
|
parent = parent->Parent();
|
2011-05-20 05:17:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2011-01-12 02:49:00 +00:00
|
|
|
// Gecko child indices are 0-based in contrast to indices used in MSAA.
|
|
|
|
return GetChildAt(aVarChild.lVal - 1);
|
2003-04-01 20:02:51 +00:00
|
|
|
}
|
|
|
|
|
2007-06-14 17:12:50 +00:00
|
|
|
void nsAccessibleWrap::UpdateSystemCaret()
|
|
|
|
{
|
|
|
|
// Move the system caret so that Windows Tablet Edition and tradional ATs with
|
|
|
|
// off-screen model can follow the caret
|
|
|
|
::DestroyCaret();
|
|
|
|
|
2012-05-04 06:09:22 +00:00
|
|
|
a11y::RootAccessible* rootAccessible = RootAccessible();
|
2007-06-14 17:12:50 +00:00
|
|
|
if (!rootAccessible) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
|
|
|
|
if (!caretAccessible) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIWidget *widget;
|
2009-01-15 03:27:09 +00:00
|
|
|
nsIntRect caretRect = caretAccessible->GetCaretRect(&widget);
|
2007-06-14 17:12:50 +00:00
|
|
|
HWND caretWnd;
|
|
|
|
if (caretRect.IsEmpty() || !(caretWnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create invisible bitmap for caret, otherwise its appearance interferes
|
|
|
|
// with Gecko caret
|
|
|
|
HBITMAP caretBitMap = CreateBitmap(1, caretRect.height, 1, 1, NULL);
|
|
|
|
if (::CreateCaret(caretWnd, caretBitMap, 1, caretRect.height)) { // Also destroys the last caret
|
|
|
|
::ShowCaret(caretWnd);
|
|
|
|
RECT windowRect;
|
|
|
|
::GetWindowRect(caretWnd, &windowRect);
|
|
|
|
::SetCaretPos(caretRect.x - windowRect.left, caretRect.y - windowRect.top);
|
|
|
|
::DeleteObject(caretBitMap);
|
|
|
|
}
|
|
|
|
}
|
2010-01-08 06:50:38 +00:00
|
|
|
|
|
|
|
ITypeInfo*
|
|
|
|
nsAccessibleWrap::GetTI(LCID lcid)
|
|
|
|
{
|
2012-01-06 03:45:27 +00:00
|
|
|
if (gTypeInfo)
|
|
|
|
return gTypeInfo;
|
2010-01-08 06:50:38 +00:00
|
|
|
|
|
|
|
ITypeLib *typeLib = NULL;
|
|
|
|
HRESULT hr = LoadRegTypeLib(LIBID_Accessibility, 1, 0, lcid, &typeLib);
|
|
|
|
if (FAILED(hr))
|
|
|
|
return NULL;
|
|
|
|
|
2012-01-06 03:45:27 +00:00
|
|
|
hr = typeLib->GetTypeInfoOfGuid(IID_IAccessible, &gTypeInfo);
|
2010-01-08 06:50:38 +00:00
|
|
|
typeLib->Release();
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
return NULL;
|
|
|
|
|
2012-01-06 03:45:27 +00:00
|
|
|
return gTypeInfo;
|
2010-01-08 06:50:38 +00:00
|
|
|
}
|