summaryrefslogtreecommitdiffstats
path: root/views/accessibility
diff options
context:
space:
mode:
Diffstat (limited to 'views/accessibility')
-rw-r--r--views/accessibility/view_accessibility.cc81
-rw-r--r--views/accessibility/view_accessibility.h9
-rw-r--r--views/accessibility/view_accessibility_wrapper.cc14
-rw-r--r--views/accessibility/view_accessibility_wrapper.h2
4 files changed, 105 insertions, 1 deletions
diff --git a/views/accessibility/view_accessibility.cc b/views/accessibility/view_accessibility.cc
index 03d03bb..0b8f4af 100644
--- a/views/accessibility/view_accessibility.cc
+++ b/views/accessibility/view_accessibility.cc
@@ -7,6 +7,13 @@
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/widget/widget.h"
+const wchar_t kViewsUninitializeAccessibilityInstance[] =
+ L"Views_Uninitialize_AccessibilityInstance";
+
+const wchar_t kViewsNativeHostPropForAccessibility[] =
+ L"Views_NativeViewHostHWNDForAccessibility";
+
+
HRESULT ViewAccessibility::Initialize(views::View* view) {
if (!view) {
return E_INVALIDARG;
@@ -23,6 +30,10 @@ STDMETHODIMP ViewAccessibility::accHitTest(LONG x_left, LONG y_top,
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
gfx::Point pt(x_left, y_top);
views::View::ConvertPointToView(NULL, view_, &pt);
@@ -82,6 +93,10 @@ STDMETHODIMP ViewAccessibility::accLocation(LONG* x_left, LONG* y_top,
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
gfx::Rect view_bounds;
// Retrieving the parent View to be used for converting from view-to-screen
// coordinates.
@@ -126,6 +141,10 @@ STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start,
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
switch (nav_dir) {
case NAVDIR_FIRSTCHILD:
case NAVDIR_LASTCHILD: {
@@ -181,7 +200,7 @@ STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start,
// Check navigation bounds, adjusting for View child indexing (MSAA
// child indexing starts with 1, whereas View indexing starts with 0).
if (!IsValidNav(nav_dir, view_index, -1,
- parent->GetChildViewCount())) {
+ parent->GetChildViewCount() - 1)) {
// Navigation attempted to go out-of-bounds.
end->vt = VT_EMPTY;
return S_FALSE;
@@ -261,6 +280,10 @@ STDMETHODIMP ViewAccessibility::get_accChild(VARIANT var_child,
return S_OK;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
views::View* child_view = NULL;
bool get_iaccessible = false;
@@ -293,6 +316,12 @@ STDMETHODIMP ViewAccessibility::get_accChild(VARIANT var_child,
return E_NOINTERFACE;
}
} else {
+ if (child_view->GetClassName() == views::NativeViewHost::kViewClassName) {
+ views::NativeViewHost* native_host =
+ static_cast<views::NativeViewHost*>(child_view);
+ if (GetNativeIAccessibleInterface(native_host, disp_child) == S_OK)
+ return S_OK;
+ }
// When at a leaf, children are handled by the parent object.
*disp_child = NULL;
return S_FALSE;
@@ -304,6 +333,10 @@ STDMETHODIMP ViewAccessibility::get_accChildCount(LONG* child_count) {
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
*child_count = view_->GetChildViewCount();
return S_OK;
}
@@ -314,6 +347,10 @@ STDMETHODIMP ViewAccessibility::get_accDefaultAction(VARIANT var_id,
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
std::wstring temp_action;
if (var_id.lVal == CHILDID_SELF) {
@@ -363,6 +400,10 @@ STDMETHODIMP ViewAccessibility::get_accFocus(VARIANT* focus_child) {
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
if (view_->GetChildViewCount() == 0 && view_->HasFocus()) {
// Parent view has focus.
focus_child->vt = VT_I4;
@@ -401,6 +442,10 @@ STDMETHODIMP ViewAccessibility::get_accKeyboardShortcut(VARIANT var_id,
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
std::wstring temp_key;
if (var_id.lVal == CHILDID_SELF) {
@@ -426,6 +471,10 @@ STDMETHODIMP ViewAccessibility::get_accName(VARIANT var_id, BSTR* name) {
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
std::wstring temp_name;
if (var_id.lVal == CHILDID_SELF) {
@@ -454,6 +503,10 @@ STDMETHODIMP ViewAccessibility::get_accParent(IDispatch** disp_parent) {
return E_INVALIDARG;
}
+ if (!view_) {
+ return E_FAIL;
+ }
+
views::View* parent_view = view_->GetParent();
if (!parent_view) {
@@ -705,6 +758,32 @@ STDMETHODIMP ViewAccessibility::put_accName(VARIANT var_id, BSTR put_name) {
}
STDMETHODIMP ViewAccessibility::put_accValue(VARIANT var_id, BSTR put_val) {
+ if (V_VT(&var_id) == VT_BSTR) {
+ if (!lstrcmpi(var_id.bstrVal, kViewsUninitializeAccessibilityInstance)) {
+ view_ = NULL;
+ return S_OK;
+ }
+ }
// Deprecated.
return E_NOTIMPL;
}
+
+HRESULT ViewAccessibility::GetNativeIAccessibleInterface(
+ views::NativeViewHost* native_host, IDispatch** disp_child) {
+ if (!native_host || !disp_child) {
+ return E_INVALIDARG;
+ }
+
+ HWND render_view_window =
+ static_cast<HWND>(GetProp(native_host->native_view(),
+ kViewsNativeHostPropForAccessibility));
+
+ if (IsWindow(render_view_window)) {
+ LRESULT ret = SendMessage(render_view_window, WM_GETOBJECT, 0,
+ OBJID_CLIENT);
+ return ObjectFromLresult(ret, IID_IDispatch, 0,
+ reinterpret_cast<void**>(disp_child));
+ }
+
+ return E_FAIL;
+}
diff --git a/views/accessibility/view_accessibility.h b/views/accessibility/view_accessibility.h
index bc1c26f..57eb45d 100644
--- a/views/accessibility/view_accessibility.h
+++ b/views/accessibility/view_accessibility.h
@@ -10,6 +10,7 @@
#include <oleacc.h>
+#include "views/controls/native/native_view_host.h"
#include "views/view.h"
////////////////////////////////////////////////////////////////////////////////
@@ -135,10 +136,18 @@ class ATL_NO_VTABLE ViewAccessibility
// to MSAA states set.
long MSAAState(AccessibilityTypes::State state);
+ // Returns the IAccessible interface for a native view if applicable.
+ // Returns S_OK on success.
+ HRESULT GetNativeIAccessibleInterface(views::NativeViewHost* native_host,
+ IDispatch** disp_child);
+
// Member View needed for view-specific calls.
views::View* view_;
DISALLOW_EVIL_CONSTRUCTORS(ViewAccessibility);
};
+extern const wchar_t kViewsUninitializeAccessibilityInstance[];
+extern const wchar_t kViewsNativeHostPropForAccessibility[];
+
#endif // VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_
diff --git a/views/accessibility/view_accessibility_wrapper.cc b/views/accessibility/view_accessibility_wrapper.cc
index 7e7f5a6..989c90a 100644
--- a/views/accessibility/view_accessibility_wrapper.cc
+++ b/views/accessibility/view_accessibility_wrapper.cc
@@ -4,6 +4,8 @@
#include "views/accessibility/view_accessibility_wrapper.h"
+#include "base/scoped_variant_win.h"
+
#include "views/accessibility/view_accessibility.h"
////////////////////////////////////////////////////////////////////////////////
@@ -43,6 +45,18 @@ STDMETHODIMP ViewAccessibilityWrapper::CreateDefaultInstance(REFIID iid) {
return E_NOINTERFACE;
}
+HRESULT ViewAccessibilityWrapper::Uninitialize() {
+ view_ = NULL;
+ if (accessibility_info_.get()) {
+ accessibility_info_->put_accValue(
+ ScopedVariant(kViewsUninitializeAccessibilityInstance), NULL);
+ ::CoDisconnectObject(accessibility_info_.get(), 0);
+ accessibility_info_ = NULL;
+ }
+
+ return S_OK;
+}
+
STDMETHODIMP ViewAccessibilityWrapper::GetInstance(REFIID iid,
void** interface_ptr) {
if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) {
diff --git a/views/accessibility/view_accessibility_wrapper.h b/views/accessibility/view_accessibility_wrapper.h
index 8ea1743..619c91d 100644
--- a/views/accessibility/view_accessibility_wrapper.h
+++ b/views/accessibility/view_accessibility_wrapper.h
@@ -32,6 +32,8 @@ class ViewAccessibilityWrapper {
STDMETHODIMP CreateDefaultInstance(REFIID iid);
+ HRESULT Uninitialize();
+
// Returns a pointer to a specified interface on an object to which a client
// currently holds an interface pointer. If pointer exists, it is reused,
// otherwise a new pointer is created. Used by accessibility implementation to