wxRichTextCtrl: Basic screen reader support

Add rudimentary (IAccessibility/MSAA) accessibility to wxRichTextCtrl to
allow screen readers to read the rich text content as plain text on
Windows. Full accessibility support would require using IAccessibility2
and IAccessibilityText (contextual reading of lines or characters, etc.)
which is not yet implemented, but in the meanwhile this is better than
nothing.

See #26051 which is somewhat mitigated even if not really fixed by this.
This commit is contained in:
Joshua Lee Ockert
2026-02-17 19:20:28 -05:00
committed by Vadim Zeitlin
parent 079b891f3b
commit 9184f60958
2 changed files with 67 additions and 0 deletions

View File

@@ -2303,6 +2303,10 @@ protected:
#endif
#endif // !__WXUNIVERSAL__
#if wxUSE_ACCESSIBILITY
virtual wxAccessible *CreateAccessible() override;
#endif
// Overrides
protected:

View File

@@ -5583,5 +5583,68 @@ int wxRichTextContextMenuPropertiesInfo::AddItems(wxRichTextCtrl* ctrl, wxRichTe
return GetCount();
}
#if wxUSE_ACCESSIBILITY
#include "wx/access.h"
class wxRichTextCtrlAccessible : public wxWindowAccessible
{
public:
explicit wxRichTextCtrlAccessible(wxRichTextCtrl *win) : wxWindowAccessible(win)
{
}
wxAccStatus GetName(int childId, wxString *name) override
{
if (childId != wxACC_SELF)
return wxWindowAccessible::GetName(childId, name);
*name = _("Rich Text Control"); // wxString::operator= copies, so this is safe
return wxACC_OK;
}
wxAccStatus GetRole(int childId, wxAccRole *role) override
{
if (childId != wxACC_SELF)
return wxWindowAccessible::GetRole(childId, role);
*role = wxROLE_SYSTEM_TEXT;
return wxACC_OK;
}
wxAccStatus GetState(int childId, long *state) override
{
if (childId != wxACC_SELF)
return wxWindowAccessible::GetState(childId, state);
wxRichTextCtrl *ctrl = wxStaticCast(GetWindow(), wxRichTextCtrl);
*state = wxACC_STATE_SYSTEM_FOCUSABLE;
if (ctrl->HasFocus())
*state |= wxACC_STATE_SYSTEM_FOCUSED;
if (!ctrl->IsEditable())
*state |= wxACC_STATE_SYSTEM_READONLY;
return wxACC_OK;
}
wxAccStatus GetValue(int childId, wxString *strValue) override
{
if (childId != wxACC_SELF)
return wxWindowAccessible::GetValue(childId, strValue);
wxRichTextCtrl *ctrl = wxStaticCast(GetWindow(), wxRichTextCtrl);
*strValue = ctrl->GetValue();
return wxACC_OK;
}
};
wxAccessible *wxRichTextCtrl::CreateAccessible()
{
return new wxRichTextCtrlAccessible(this);
}
#endif // wxUSE_ACCESSIBILITY
#endif
// wxUSE_RICHTEXT