summaryrefslogtreecommitdiff
path: root/tests/cefclient/browser/osr_accessibility_node_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cefclient/browser/osr_accessibility_node_win.cc')
-rw-r--r--tests/cefclient/browser/osr_accessibility_node_win.cc739
1 files changed, 739 insertions, 0 deletions
diff --git a/tests/cefclient/browser/osr_accessibility_node_win.cc b/tests/cefclient/browser/osr_accessibility_node_win.cc
new file mode 100644
index 00000000..5c5e64fb
--- /dev/null
+++ b/tests/cefclient/browser/osr_accessibility_node_win.cc
@@ -0,0 +1,739 @@
+// Copyright 2017 The Chromium Embedded Framework Authors. Portions copyright
+// 2013 The Chromium Authors. All rights reserved. Use of this source code is
+// governed by a BSD-style license that can be found in the LICENSE file.
+
+// This class implements our accessible proxy object that handles moving
+// data back and forth between MSAA clients and CefClient renderers.
+// Sample implementation based on ui\accessibility\ax_platform_node_win.h
+
+#include "tests/cefclient/browser/osr_accessibility_node.h"
+
+#if defined(CEF_USE_ATL)
+
+#include <atlbase.h>
+#include <oleacc.h>
+#include <string>
+
+#include "tests/cefclient/browser/osr_accessibility_helper.h"
+
+namespace client {
+
+// Return CO_E_OBJNOTCONNECTED for accessible objects thar still exists but the
+// window and/or object it references has been destroyed.
+#define DATACHECK(node) (node) ? S_OK : CO_E_OBJNOTCONNECTED
+#define VALID_CHILDID(varChild) ((varChild.vt == VT_I4))
+
+namespace {
+
+// Helper function to convert a rectangle from client coordinates to screen
+// coordinates.
+void ClientToScreen(HWND hwnd, LPRECT lpRect) {
+ if (lpRect) {
+ POINT ptTL = {lpRect->left, lpRect->top};
+ POINT ptBR = {lpRect->right, lpRect->bottom};
+ // Win32 API only provides the call for a point.
+ ClientToScreen(hwnd, &ptTL);
+ ClientToScreen(hwnd, &ptBR);
+ SetRect(lpRect, ptTL.x, ptTL.y, ptBR.x, ptBR.y);
+ }
+}
+
+// Helper function to convert to MSAARole
+int AxRoleToMSAARole(const std::string& role_string) {
+ if (role_string == "alert") {
+ return ROLE_SYSTEM_ALERT;
+ }
+ if (role_string == "application") {
+ return ROLE_SYSTEM_APPLICATION;
+ }
+ if (role_string == "buttonDropDown") {
+ return ROLE_SYSTEM_BUTTONDROPDOWN;
+ }
+ if (role_string == "popUpButton") {
+ return ROLE_SYSTEM_BUTTONMENU;
+ }
+ if (role_string == "checkBox") {
+ return ROLE_SYSTEM_CHECKBUTTON;
+ }
+ if (role_string == "comboBox") {
+ return ROLE_SYSTEM_COMBOBOX;
+ }
+ if (role_string == "dialog") {
+ return ROLE_SYSTEM_DIALOG;
+ }
+ if (role_string == "genericContainer") {
+ return ROLE_SYSTEM_GROUPING;
+ }
+ if (role_string == "group") {
+ return ROLE_SYSTEM_GROUPING;
+ }
+ if (role_string == "image") {
+ return ROLE_SYSTEM_GRAPHIC;
+ }
+ if (role_string == "link") {
+ return ROLE_SYSTEM_LINK;
+ }
+ if (role_string == "locationBar") {
+ return ROLE_SYSTEM_GROUPING;
+ }
+ if (role_string == "menuBar") {
+ return ROLE_SYSTEM_MENUBAR;
+ }
+ if (role_string == "menuItem") {
+ return ROLE_SYSTEM_MENUITEM;
+ }
+ if (role_string == "menuListPopup") {
+ return ROLE_SYSTEM_MENUPOPUP;
+ }
+ if (role_string == "tree") {
+ return ROLE_SYSTEM_OUTLINE;
+ }
+ if (role_string == "treeItem") {
+ return ROLE_SYSTEM_OUTLINEITEM;
+ }
+ if (role_string == "tab") {
+ return ROLE_SYSTEM_PAGETAB;
+ }
+ if (role_string == "tabList") {
+ return ROLE_SYSTEM_PAGETABLIST;
+ }
+ if (role_string == "pane") {
+ return ROLE_SYSTEM_PANE;
+ }
+ if (role_string == "progressIndicator") {
+ return ROLE_SYSTEM_PROGRESSBAR;
+ }
+ if (role_string == "button") {
+ return ROLE_SYSTEM_PUSHBUTTON;
+ }
+ if (role_string == "radioButton") {
+ return ROLE_SYSTEM_RADIOBUTTON;
+ }
+ if (role_string == "scrollBar") {
+ return ROLE_SYSTEM_SCROLLBAR;
+ }
+ if (role_string == "splitter") {
+ return ROLE_SYSTEM_SEPARATOR;
+ }
+ if (role_string == "slider") {
+ return ROLE_SYSTEM_SLIDER;
+ }
+ if (role_string == "staticText") {
+ return ROLE_SYSTEM_STATICTEXT;
+ }
+ if (role_string == "textField") {
+ return ROLE_SYSTEM_TEXT;
+ }
+ if (role_string == "titleBar") {
+ return ROLE_SYSTEM_TITLEBAR;
+ }
+ if (role_string == "toolbar") {
+ return ROLE_SYSTEM_TOOLBAR;
+ }
+ if (role_string == "webView") {
+ return ROLE_SYSTEM_GROUPING;
+ }
+ if (role_string == "window") {
+ return ROLE_SYSTEM_WINDOW;
+ }
+ if (role_string == "client") {
+ return ROLE_SYSTEM_CLIENT;
+ }
+ // This is the default role for MSAA.
+ return ROLE_SYSTEM_CLIENT;
+}
+
+static inline int MiddleX(const CefRect& rect) {
+ return rect.x + rect.width / 2;
+}
+
+static inline int MiddleY(const CefRect& rect) {
+ return rect.y + rect.height / 2;
+}
+
+} // namespace
+
+struct CefIAccessible : public IAccessible {
+ public:
+ // Implement IUnknown
+ STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) override;
+ STDMETHODIMP_(ULONG) AddRef() override;
+ STDMETHODIMP_(ULONG) Release() override;
+
+ //
+ // IAccessible methods.
+ //
+ // Retrieves the child element or child object at a given point on the screen.
+ STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child) override;
+
+ // Performs the object's default action.
+ STDMETHODIMP accDoDefaultAction(VARIANT var_id) override;
+
+ // Retrieves the specified object's current screen location.
+ STDMETHODIMP accLocation(LONG* x_left,
+ LONG* y_top,
+ LONG* width,
+ LONG* height,
+ VARIANT var_id) override;
+
+ // Traverses to another UI element and retrieves the object.
+ STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end) override;
+
+ // Retrieves an IDispatch interface pointer for the specified child.
+ STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child) override;
+
+ // Retrieves the number of accessible children.
+ STDMETHODIMP get_accChildCount(LONG* child_count) override;
+
+ // Retrieves a string that describes the object's default action.
+ STDMETHODIMP get_accDefaultAction(VARIANT var_id,
+ BSTR* default_action) override;
+
+ // Retrieves the tooltip description.
+ STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc) override;
+
+ // Retrieves the object that has the keyboard focus.
+ STDMETHODIMP get_accFocus(VARIANT* focus_child) override;
+
+ // Retrieves the specified object's shortcut.
+ STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id,
+ BSTR* access_key) override;
+
+ // Retrieves the name of the specified object.
+ STDMETHODIMP get_accName(VARIANT var_id, BSTR* name) override;
+
+ // Retrieves the IDispatch interface of the object's parent.
+ STDMETHODIMP get_accParent(IDispatch** disp_parent) override;
+
+ // Retrieves information describing the role of the specified object.
+ STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role) override;
+
+ // Retrieves the current state of the specified object.
+ STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state) override;
+
+ // Gets the help string for the specified object.
+ STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help) override;
+
+ // Retrieve or set the string value associated with the specified object.
+ // Setting the value is not typically used by screen readers, but it's
+ // used frequently by automation software.
+ STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value) override;
+ STDMETHODIMP put_accValue(VARIANT var_id, BSTR new_value) override;
+
+ // IAccessible methods not implemented.
+ STDMETHODIMP get_accSelection(VARIANT* selected) override;
+ STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id) override;
+ STDMETHODIMP get_accHelpTopic(BSTR* help_file,
+ VARIANT var_id,
+ LONG* topic_id) override;
+ STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) override;
+
+ // Implement IDispatch
+ STDMETHODIMP GetTypeInfoCount(unsigned int FAR* pctinfo) override;
+ STDMETHODIMP GetTypeInfo(unsigned int iTInfo,
+ LCID lcid,
+ ITypeInfo FAR* FAR* ppTInfo) override;
+ STDMETHODIMP GetIDsOfNames(REFIID riid,
+ OLECHAR FAR* FAR* rgszNames,
+ unsigned int cNames,
+ LCID lcid,
+ DISPID FAR* rgDispId) override;
+ STDMETHODIMP Invoke(DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS FAR* pDispParams,
+ VARIANT FAR* pVarResult,
+ EXCEPINFO FAR* pExcepInfo,
+ unsigned int FAR* puArgErr) override;
+
+ CefIAccessible(OsrAXNode* node) : ref_count_(0), node_(node) {}
+
+ // Remove the node reference when OsrAXNode is destroyed, so that
+ // MSAA clients get CO_E_OBJNOTCONNECTED
+ void MarkDestroyed() { node_ = nullptr; }
+
+ protected:
+ virtual ~CefIAccessible() {}
+
+ // Ref Count
+ ULONG ref_count_;
+ // OsrAXNode* proxy object
+ OsrAXNode* node_;
+};
+
+// Implement IUnknown
+// *********************
+
+// Handles ref counting and querying for other supported interfaces.
+// We only support, IUnknown, IDispatch and IAccessible.
+STDMETHODIMP CefIAccessible::QueryInterface(REFIID riid, void** ppvObject) {
+ if (riid == IID_IAccessible) {
+ *ppvObject = static_cast<IAccessible*>(this);
+ } else if (riid == IID_IDispatch) {
+ *ppvObject = static_cast<IDispatch*>(this);
+ } else if (riid == IID_IUnknown) {
+ *ppvObject = static_cast<IUnknown*>(this);
+ } else {
+ *ppvObject = nullptr;
+ }
+
+ if (*ppvObject) {
+ reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
+ }
+
+ return (*ppvObject) ? S_OK : E_NOINTERFACE;
+}
+
+// Increments COM objects refcount required by IUnknown for reference counting
+STDMETHODIMP_(ULONG) CefIAccessible::AddRef() {
+ return InterlockedIncrement((LONG volatile*)&ref_count_);
+}
+
+STDMETHODIMP_(ULONG) CefIAccessible::Release() {
+ ULONG ulRefCnt = InterlockedDecrement((LONG volatile*)&ref_count_);
+ if (ulRefCnt == 0) {
+ // Remove reference from OsrAXNode
+ if (node_) {
+ node_->Destroy();
+ }
+ delete this;
+ }
+
+ return ulRefCnt;
+}
+
+// Implement IAccessible
+// *********************
+
+// Returns the parent IAccessible in the form of an IDispatch interface.
+STDMETHODIMP CefIAccessible::get_accParent(IDispatch** ppdispParent) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (ppdispParent) {
+ CefNativeAccessible* parent = node_->GetParentAccessibleObject();
+ if (!parent) {
+ // Find our parent window
+ HWND hWnd = ::GetParent(node_->GetWindowHandle());
+ // if we have a window attempt to get its IAccessible pointer
+ if (hWnd) {
+ AccessibleObjectFromWindow(hWnd, (DWORD)OBJID_CLIENT, IID_IAccessible,
+ (void**)(&parent));
+ }
+ }
+
+ if (parent) {
+ parent->AddRef();
+ }
+ *ppdispParent = parent;
+ retCode = (*ppdispParent) ? S_OK : S_FALSE;
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ return retCode;
+}
+
+// Returns the number of children we have for this element.
+STDMETHODIMP CefIAccessible::get_accChildCount(long* pcountChildren) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode) && pcountChildren) {
+ // Get Child node count for this from Accessibility tree
+ *pcountChildren = node_->GetChildCount();
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ return retCode;
+}
+
+// Returns a child IAccessible object.
+STDMETHODIMP CefIAccessible::get_accChild(VARIANT varChild,
+ IDispatch** ppdispChild) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ int numChilds = node_->GetChildCount();
+ // Mark Leaf node if there are no child
+ if (numChilds <= 0) {
+ *ppdispChild = nullptr;
+ return S_FALSE;
+ } else {
+ if (ppdispChild && VALID_CHILDID(varChild)) {
+ if (varChild.lVal == CHILDID_SELF) {
+ *ppdispChild = this;
+ } else {
+ // Convert to 0 based index and get Child Node.
+ OsrAXNode* child = node_->ChildAtIndex(varChild.lVal - 1);
+ // Fallback to focused node
+ if (!child) {
+ child = node_->GetAccessibilityHelper()->GetFocusedNode();
+ }
+
+ *ppdispChild = child->GetNativeAccessibleObject(node_);
+ }
+ if (*ppdispChild == nullptr) {
+ retCode = S_FALSE;
+ } else {
+ (*ppdispChild)->AddRef();
+ }
+ }
+ }
+ }
+ return retCode;
+}
+
+// Check and returns the accessible name for element from accessibility tree
+STDMETHODIMP CefIAccessible::get_accName(VARIANT varChild, BSTR* pszName) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pszName && VALID_CHILDID(varChild)) {
+ std::wstring name = node_->AxName();
+ CComBSTR bstrResult(name.c_str());
+ *pszName = bstrResult.Detach();
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ return retCode;
+}
+
+// Check and returns the value for element from accessibility tree
+STDMETHODIMP CefIAccessible::get_accValue(VARIANT varChild, BSTR* pszValue) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pszValue && VALID_CHILDID(varChild)) {
+ std::wstring name = node_->AxValue();
+ CComBSTR bstrResult(name.c_str());
+ *pszValue = bstrResult.Detach();
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ return retCode;
+}
+
+// Check and returns the description for element from accessibility tree
+STDMETHODIMP CefIAccessible::get_accDescription(VARIANT varChild,
+ BSTR* pszDescription) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pszDescription && VALID_CHILDID(varChild)) {
+ std::wstring name = node_->AxDescription();
+ CComBSTR bstrResult(name.c_str());
+ *pszDescription = bstrResult.Detach();
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ return retCode;
+}
+
+// Check and returns the MSAA Role for element from accessibility tree
+STDMETHODIMP CefIAccessible::get_accRole(VARIANT varChild, VARIANT* pvarRole) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ // Get the accessibilty role and Map to MSAA Role
+ if (pvarRole) {
+ pvarRole->vt = VT_I4;
+ pvarRole->lVal = AxRoleToMSAARole(node_->AxRole());
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+ return retCode;
+}
+
+// Check and returns Accessibility State for element from accessibility tree
+STDMETHODIMP CefIAccessible::get_accState(VARIANT varChild,
+ VARIANT* pvarState) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pvarState) {
+ pvarState->vt = VT_I4;
+ pvarState->lVal =
+ (GetFocus() == node_->GetWindowHandle()) ? STATE_SYSTEM_FOCUSED : 0;
+ pvarState->lVal |= STATE_SYSTEM_PRESSED;
+ pvarState->lVal |= STATE_SYSTEM_FOCUSABLE;
+
+ // For child
+ if (varChild.lVal == CHILDID_SELF) {
+ DWORD dwStyle = GetWindowLong(node_->GetWindowHandle(), GWL_STYLE);
+ pvarState->lVal |=
+ ((dwStyle & WS_VISIBLE) == 0) ? STATE_SYSTEM_INVISIBLE : 0;
+ pvarState->lVal |=
+ ((dwStyle & WS_DISABLED) > 0) ? STATE_SYSTEM_UNAVAILABLE : 0;
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+ return retCode;
+}
+
+// Check and returns Accessibility Shortcut if any for element
+STDMETHODIMP CefIAccessible::get_accKeyboardShortcut(
+ VARIANT varChild,
+ BSTR* pszKeyboardShortcut) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pszKeyboardShortcut && VALID_CHILDID(varChild)) {
+ *pszKeyboardShortcut = ::SysAllocString(L"None");
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+ return retCode;
+}
+
+// Return focused element from the accessibility tree
+STDMETHODIMP CefIAccessible::get_accFocus(VARIANT* pFocusChild) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ OsrAXNode* focusedNode = node_->GetAccessibilityHelper()->GetFocusedNode();
+ CefNativeAccessible* nativeObj = nullptr;
+ if (focusedNode) {
+ nativeObj = focusedNode->GetNativeAccessibleObject(nullptr);
+ }
+
+ if (nativeObj) {
+ if (nativeObj == this) {
+ pFocusChild->vt = VT_I4;
+ pFocusChild->lVal = CHILDID_SELF;
+ } else {
+ pFocusChild->vt = VT_DISPATCH;
+ pFocusChild->pdispVal = nativeObj;
+ pFocusChild->pdispVal->AddRef();
+ }
+ } else {
+ pFocusChild->vt = VT_EMPTY;
+ }
+ }
+ return retCode;
+}
+
+// Return a selection list for multiple selection items.
+STDMETHODIMP CefIAccessible::get_accSelection(VARIANT* pvarChildren) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pvarChildren) {
+ pvarChildren->vt = VT_EMPTY;
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+ return retCode;
+}
+
+// Return a string description of the default action of our element, eg. push
+STDMETHODIMP CefIAccessible::get_accDefaultAction(VARIANT varChild,
+ BSTR* pszDefaultAction) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pszDefaultAction && VALID_CHILDID(varChild)) {
+ *pszDefaultAction = ::SysAllocString(L"Push");
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+ return retCode;
+}
+
+// child item selectionor for an item to take focus.
+STDMETHODIMP CefIAccessible::accSelect(long flagsSelect, VARIANT varChild) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (VALID_CHILDID(varChild)) {
+ HWND hwnd = node_->GetWindowHandle();
+ // we only support SELFLAG_TAKEFOCUS.
+ if (((flagsSelect & SELFLAG_TAKEFOCUS) > 0) && (GetFocus() == hwnd)) {
+ RECT rcWnd;
+ GetClientRect(hwnd, &rcWnd);
+ InvalidateRect(hwnd, &rcWnd, FALSE);
+ } else {
+ retCode = S_FALSE;
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+
+ return retCode;
+}
+
+// Returns back the screen coordinates of our element or one of its childs
+STDMETHODIMP CefIAccessible::accLocation(long* pxLeft,
+ long* pyTop,
+ long* pcxWidth,
+ long* pcyHeight,
+ VARIANT varChild) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pxLeft && pyTop && pcxWidth && pcyHeight && VALID_CHILDID(varChild)) {
+ CefRect loc = node_->AxLocation();
+ RECT rcItem = {loc.x, loc.y, loc.x + loc.width, loc.y + loc.height};
+ HWND hwnd = node_->GetWindowHandle();
+ ClientToScreen(hwnd, &rcItem);
+
+ *pxLeft = rcItem.left;
+ *pyTop = rcItem.top;
+ *pcxWidth = rcItem.right - rcItem.left;
+ *pcyHeight = rcItem.bottom - rcItem.top;
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+ return retCode;
+}
+
+// Allow clients to move the keyboard focus within the control
+// Deprecated
+STDMETHODIMP CefIAccessible::accNavigate(long navDir,
+ VARIANT varStart,
+ VARIANT* pvarEndUpAt) {
+ return E_NOTIMPL;
+}
+
+// Check if the coordinates provided are within our element or child items.
+STDMETHODIMP CefIAccessible::accHitTest(long xLeft,
+ long yTop,
+ VARIANT* pvarChild) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode)) {
+ if (pvarChild) {
+ pvarChild->vt = VT_EMPTY;
+
+ CefRect loc = node_->AxLocation();
+ RECT rcItem = {loc.x, loc.y, loc.x + loc.width, loc.y + loc.height};
+ POINT pt = {xLeft, yTop};
+
+ ClientToScreen(node_->GetWindowHandle(), &rcItem);
+
+ if (PtInRect(&rcItem, pt)) {
+ pvarChild->vt = VT_I4;
+ pvarChild->lVal = 1;
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+ }
+
+ return retCode;
+}
+
+// Forces the default action of our element. In simplest cases, send a click.
+STDMETHODIMP CefIAccessible::accDoDefaultAction(VARIANT varChild) {
+ HRESULT retCode = DATACHECK(node_);
+ if (SUCCEEDED(retCode) && VALID_CHILDID(varChild)) {
+ // doing our default action for out button is to simply click the button.
+ CefRefPtr<CefBrowser> browser = node_->GetBrowser();
+ if (browser) {
+ CefMouseEvent mouse_event;
+ const CefRect& rect = node_->AxLocation();
+ mouse_event.x = MiddleX(rect);
+ mouse_event.y = MiddleY(rect);
+
+ mouse_event.modifiers = 0;
+ browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_LEFT, false, 1);
+ browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_LEFT, true, 1);
+ }
+ } else {
+ retCode = E_INVALIDARG;
+ }
+
+ return retCode;
+}
+
+// Set the name for an element in the accessibility tree
+STDMETHODIMP CefIAccessible::put_accName(VARIANT varChild, BSTR szName) {
+ return E_NOTIMPL;
+}
+
+// Set the value for an element in the accessibility tree
+STDMETHODIMP CefIAccessible::put_accValue(VARIANT varChild, BSTR szValue) {
+ return E_NOTIMPL;
+}
+
+// Return E_NOTIMPL as no help file/ topic
+STDMETHODIMP CefIAccessible::get_accHelp(VARIANT varChild, BSTR* pszHelp) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CefIAccessible::get_accHelpTopic(BSTR* pszHelpFile,
+ VARIANT varChild,
+ long* pidTopic) {
+ return E_NOTIMPL;
+}
+
+// IDispatch - We are not going to return E_NOTIMPL from IDispatch methods and
+// let Active Accessibility implement the IAccessible interface for them.
+STDMETHODIMP CefIAccessible::GetTypeInfoCount(unsigned int FAR* pctinfo) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CefIAccessible::GetTypeInfo(unsigned int iTInfo,
+ LCID lcid,
+ ITypeInfo FAR* FAR* ppTInfo) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CefIAccessible::GetIDsOfNames(REFIID riid,
+ OLECHAR FAR* FAR* rgszNames,
+ unsigned int cNames,
+ LCID lcid,
+ DISPID FAR* rgDispId) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CefIAccessible::Invoke(DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS FAR* pDispParams,
+ VARIANT FAR* pVarResult,
+ EXCEPINFO FAR* pExcepInfo,
+ unsigned int FAR* puArgErr) {
+ return E_NOTIMPL;
+}
+
+void OsrAXNode::NotifyAccessibilityEvent(std::string event_type) const {
+ if (event_type == "focus") {
+ // Notify Screen Reader of focus change
+ ::NotifyWinEvent(EVENT_OBJECT_FOCUS, GetWindowHandle(), OBJID_CLIENT,
+ node_id_);
+ }
+}
+
+void OsrAXNode::Destroy() {
+ CefIAccessible* ptr = static_cast<CefIAccessible*>(platform_accessibility_);
+ if (ptr) {
+ ptr->MarkDestroyed();
+ }
+ platform_accessibility_ = nullptr;
+}
+
+// Create and return NSAccessibility Implementation Object for Window
+CefNativeAccessible* OsrAXNode::GetNativeAccessibleObject(OsrAXNode* parent) {
+ if (!platform_accessibility_) {
+ platform_accessibility_ = new CefIAccessible(this);
+ platform_accessibility_->AddRef();
+ SetParent(parent);
+ }
+ return platform_accessibility_;
+}
+
+} // namespace client
+
+#else // !defined(CEF_USE_ATL)
+
+namespace client {
+
+void OsrAXNode::NotifyAccessibilityEvent(std::string event_type) const {}
+
+void OsrAXNode::Destroy() {}
+
+CefNativeAccessible* OsrAXNode::GetNativeAccessibleObject(OsrAXNode* parent) {
+ return nullptr;
+}
+
+} // namespace client
+
+#endif // !defined(CEF_USE_ATL)