diff options
Diffstat (limited to 'views/accessibility')
-rw-r--r-- | views/accessibility/view_accessibility.cc | 81 | ||||
-rw-r--r-- | views/accessibility/view_accessibility.h | 9 | ||||
-rw-r--r-- | views/accessibility/view_accessibility_wrapper.cc | 14 | ||||
-rw-r--r-- | views/accessibility/view_accessibility_wrapper.h | 2 |
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 |