Chromium Code Reviews| Index: views/controls/textfield/native_textfield_win.cc |
| =================================================================== |
| --- views/controls/textfield/native_textfield_win.cc (revision 49543) |
| +++ views/controls/textfield/native_textfield_win.cc (working copy) |
| @@ -19,6 +19,7 @@ |
| #include "gfx/native_theme_win.h" |
| #include "grit/app_strings.h" |
| #include "skia/ext/skia_utils_win.h" |
| +#include "views/controls/label.h" |
| #include "views/controls/menu/menu_win.h" |
| #include "views/controls/menu/menu_2.h" |
| #include "views/controls/native/native_view_host.h" |
| @@ -105,6 +106,8 @@ |
| ole_interface.Attach(GetOleInterface()); |
| if (ole_interface) |
| text_object_model_.QueryFrom(ole_interface); |
| + |
| + InitializeAccessibilityInfo(); |
| } |
| NativeTextfieldWin::~NativeTextfieldWin() { |
| @@ -144,6 +147,7 @@ |
| if (textfield_->style() & Textfield::STYLE_LOWERCASE) |
| text_to_set = l10n_util::ToLower(text_to_set); |
| SetWindowText(text_to_set.c_str()); |
| + UpdateAccessibleValue(text_to_set); |
| } |
| void NativeTextfieldWin::AppendText(const string16& text) { |
| @@ -203,6 +207,7 @@ |
| void NativeTextfieldWin::UpdateReadOnly() { |
| SendMessage(m_hWnd, EM_SETREADONLY, textfield_->read_only(), 0); |
| + UpdateAccessibleState(STATE_SYSTEM_READONLY, textfield_->read_only()); |
| } |
| void NativeTextfieldWin::UpdateFont() { |
| @@ -214,10 +219,12 @@ |
| void NativeTextfieldWin::UpdateIsPassword() { |
| // TODO: Need to implement for Windows. |
| + UpdateAccessibleState(STATE_SYSTEM_PROTECTED, textfield_->IsPassword()); |
| } |
| void NativeTextfieldWin::UpdateEnabled() { |
| SendMessage(m_hWnd, WM_ENABLE, textfield_->IsEnabled(), 0); |
| + UpdateAccessibleState(STATE_SYSTEM_UNAVAILABLE, !textfield_->IsEnabled()); |
| } |
| gfx::Insets NativeTextfieldWin::CalculateInsets() { |
| @@ -317,6 +324,72 @@ |
| OnAfterPossibleChange(); |
| } |
| +void NativeTextfieldWin::InitializeAccessibilityInfo() { |
| + // Set the accessible state. |
| + accessibility_state_ = 0; |
| + |
| + ScopedComPtr<IAccPropServices> pAccPropServices; |
| + HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, |
| + IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); |
| + if (!SUCCEEDED(hr)) |
| + return; |
| + |
| + VARIANT var; |
| + |
| + // Set the accessible role. |
| + var.vt = VT_I4; |
| + var.lVal = ROLE_SYSTEM_TEXT; |
| + hr = pAccPropServices->SetHwndProp(m_hWnd, OBJID_CLIENT, |
| + CHILDID_SELF, PROPID_ACC_ROLE, var); |
| + |
| + // Set the accessible name by getting the label text. |
| + View* parent = textfield_->GetParent(); |
| + int label_index = parent->GetChildIndex(textfield_) - 1; |
| + if (label_index >= 0) { |
| + std::wstring name; |
| + View* label_view = parent->GetChildViewAt(label_index ); |
| + if (label_view ->GetClassName() == Label::kViewClassName && |
|
Chris Guillory
2010/06/15 17:30:16
Can we DCHECK label_view ->GetClassName() == Label
|
| + label_view ->GetAccessibleName(&name)) { |
| + |
| + hr = pAccPropServices->SetHwndPropStr(m_hWnd, OBJID_CLIENT, |
| + CHILDID_SELF, PROPID_ACC_NAME, name.c_str()); |
| + } |
| + } |
| +} |
| + |
| +void NativeTextfieldWin::UpdateAccessibleState(uint32 state_flag, |
| + bool set_value) { |
| + ScopedComPtr<IAccPropServices> pAccPropServices; |
| + HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, |
| + IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); |
| + if (!SUCCEEDED(hr)) |
| + return; |
| + |
| + VARIANT var; |
| + var.vt = VT_I4; |
| + var.lVal = set_value ? accessibility_state_ | state_flag |
| + : accessibility_state_ & ~state_flag; |
| + hr = pAccPropServices->SetHwndProp(m_hWnd, OBJID_CLIENT, |
| + CHILDID_SELF, PROPID_ACC_STATE, var); |
| + |
| + ::NotifyWinEvent(EVENT_OBJECT_STATECHANGE, m_hWnd, OBJID_CLIENT, |
| + CHILDID_SELF); |
| +} |
| + |
| +void NativeTextfieldWin::UpdateAccessibleValue(const std::wstring& value) { |
| + ScopedComPtr<IAccPropServices> pAccPropServices; |
| + HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, |
| + IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); |
| + if (!SUCCEEDED(hr)) |
| + return; |
| + |
| + hr = pAccPropServices->SetHwndPropStr(m_hWnd, OBJID_CLIENT, |
| + CHILDID_SELF, PROPID_ACC_VALUE, value.c_str()); |
| + |
| + ::NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, m_hWnd, OBJID_CLIENT, |
| + CHILDID_SELF); |
| +} |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // NativeTextfieldWin, private: |
| @@ -833,6 +906,7 @@ |
| return; |
| } |
| textfield_->SyncText(); |
| + UpdateAccessibleValue(textfield_->text()); |
| if (textfield_->GetController()) |
| textfield_->GetController()->ContentsChanged(textfield_, new_text); |
| } |