Further tweaks to accessibility code

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19256 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart 2003-02-19 16:31:28 +00:00
parent af7b5345ed
commit 2aefc52854
3 changed files with 453 additions and 234 deletions

View File

@ -93,6 +93,8 @@ public:
// Recursively give information about an object
void LogObject(int indent, IAccessible* obj);
// Get info for a child (id > 0) or object (id == 0)
void GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role);
private:
wxTextCtrl* m_textCtrl;
@ -212,7 +214,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
{
m_textCtrl = NULL;
SetAccessible(new FrameAccessible(this));
// SetAccessible(new FrameAccessible(this));
// set the frame icon
SetIcon(wxICON(mondrian));
@ -238,12 +240,13 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
SetMenuBar(menuBar);
#endif // wxUSE_MENUS
#if 1 // wxUSE_STATUSBAR
#if 0 // wxUSE_STATUSBAR
// create a status bar just for fun (by default with 1 pane only)
CreateStatusBar(2);
SetStatusText(_T("Welcome to wxWindows!"));
#endif // wxUSE_STATUSBAR
#if 1
wxSplitterWindow* splitter = new wxSplitterWindow(this, -1);
splitter->CreateAccessible();
@ -255,6 +258,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
m_textCtrl->CreateAccessible();
splitter->SplitHorizontally(listBox, m_textCtrl, 150);
#endif
#if 0
#if 1
@ -297,8 +301,67 @@ void MyFrame::OnQuery(wxCommandEvent& WXUNUSED(event))
}
if (accessibleFrame)
{
Log(wxT("Got an IAccessible for the frame."));
//Log(wxT("Got an IAccessible for the frame."));
LogObject(0, accessibleFrame);
Log(wxT("Checking children using AccessibleChildren()..."));
// Now check the AccessibleChildren function works OK
long childCount = 0;
if (S_OK != accessibleFrame->get_accChildCount(& childCount))
{
Log(wxT("Could not get number of children."));
accessibleFrame->Release();
return;
}
else if (childCount == 0)
{
Log(wxT("No children."));
accessibleFrame->Release();
return;
}
long obtained = 0;
VARIANT *var = new VARIANT[childCount];
int i;
for (i = 0; i < childCount; i++)
{
VariantInit(& (var[i]));
var[i].vt = VT_DISPATCH;
}
if (S_OK == AccessibleChildren(accessibleFrame, 0, childCount, var, &obtained))
{
for (i = 0; i < childCount; i++)
{
IAccessible* childAccessible = NULL;
if (var[i].pdispVal)
{
if (var[i].pdispVal->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
{
var[i].pdispVal->Release();
wxString name, role;
GetInfo(childAccessible, 0, name, role);
wxString str;
str.Printf(wxT("Found child %s/%s"), name.c_str(), role.c_str());
Log(str);
childAccessible->Release();
}
else
{
var[i].pdispVal->Release();
}
}
}
}
else
{
Log(wxT("AccessibleChildren failed."));
}
delete[] var;
accessibleFrame->Release();
}
}
@ -319,56 +382,16 @@ void MyFrame::Log(const wxString& text)
// Recursively give information about an object
void MyFrame::LogObject(int indent, IAccessible* obj)
{
VARIANT var;
VariantInit(& var);
var.vt = VT_I4;
var.lVal = 0;
BSTR bStrName = 0;
HRESULT hResult = obj->get_accName(var, & bStrName);
if (hResult == S_OK)
wxString name, role;
if (indent == 0)
{
wxString strName(wxConvertStringFromOle(bStrName));
SysFreeString(bStrName);
GetInfo(obj, 0, name, role);
wxString str;
str.Printf(wxT("Name: %s"), strName.c_str());
str.Printf(wxT("Name = %s; Role = %s"), name.c_str(), role.c_str());
str.Pad(indent, wxT(' '), FALSE);
Log(str);
}
else
{
wxString str;
str.Printf(wxT("NO NAME"));
str.Pad(indent, wxT(' '), FALSE);
Log(str);
}
VARIANT varRole;
VariantInit(& varRole);
hResult = obj->get_accRole(var, & varRole);
if (hResult == S_OK && varRole.vt == VT_I4)
{
wxChar buf[256];
GetRoleText(varRole.lVal, buf, 256);
wxString strRole(buf);
wxString str;
str.Printf(wxT("Role: %s"), strRole.c_str());
str.Pad(indent, wxT(' '), FALSE);
Log(str);
}
else
{
wxString str;
str.Printf(wxT("NO ROLE"));
str.Pad(indent, wxT(' '), FALSE);
Log(str);
}
long childCount = 0;
if (S_OK == obj->get_accChildCount(& childCount))
@ -377,11 +400,19 @@ void MyFrame::LogObject(int indent, IAccessible* obj)
str.Printf(wxT("There are %d children."), (int) childCount);
str.Pad(indent, wxT(' '), FALSE);
Log(str);
Log(wxT(""));
}
int i;
for (i = 1; i <= childCount; i++)
{
GetInfo(obj, i, name, role);
wxString str;
str.Printf(wxT("%d) Name = %s; Role = %s"), i, name.c_str(), role.c_str());
str.Pad(indent, wxT(' '), FALSE);
Log(str);
VARIANT var;
VariantInit(& var);
var.vt = VT_I4;
@ -389,52 +420,6 @@ void MyFrame::LogObject(int indent, IAccessible* obj)
IDispatch* pDisp = NULL;
IAccessible* childObject = NULL;
BSTR bStrName = 0;
HRESULT hResult = obj->get_accName(var, & bStrName);
if (hResult == S_OK)
{
wxString strName(wxConvertStringFromOle(bStrName));
SysFreeString(bStrName);
wxString str;
str.Printf(wxT("Name: %s"), strName.c_str());
str.Pad(indent+4, wxT(' '), FALSE);
Log(str);
}
else
{
wxString str;
str.Printf(wxT("NO NAME"));
str.Pad(indent+4, wxT(' '), FALSE);
Log(str);
}
VARIANT varRole;
VariantInit(& varRole);
hResult = obj->get_accRole(var, & varRole);
if (hResult == S_OK && varRole.vt == VT_I4)
{
wxChar buf[256];
GetRoleText(varRole.lVal, buf, 256);
wxString strRole(buf);
wxString str;
str.Printf(wxT("Role: %s"), strRole.c_str());
str.Pad(indent+4, wxT(' '), FALSE);
Log(str);
}
else
{
wxString str;
str.Printf(wxT("NO ROLE"));
str.Pad(indent+4, wxT(' '), FALSE);
Log(str);
}
if (S_OK == obj->get_accChild(var, & pDisp) && pDisp)
{
wxString str;
@ -456,8 +441,46 @@ void MyFrame::LogObject(int indent, IAccessible* obj)
str.Pad(indent+4, wxT(' '), FALSE);
Log(str);
}
Log(wxT(""));
// Log(wxT(""));
}
}
// Get info for a child (id > 0) or object (id == 0)
void MyFrame::GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role)
{
VARIANT var;
VariantInit(& var);
var.vt = VT_I4;
var.lVal = id;
BSTR bStrName = 0;
HRESULT hResult = accessible->get_accName(var, & bStrName);
if (hResult == S_OK)
{
name = wxConvertStringFromOle(bStrName);
SysFreeString(bStrName);
}
else
{
name = wxT("NO NAME");
}
VARIANT varRole;
VariantInit(& varRole);
hResult = accessible->get_accRole(var, & varRole);
if (hResult == S_OK && varRole.vt == VT_I4)
{
wxChar buf[256];
GetRoleText(varRole.lVal, buf, 256);
role = buf;
}
else
{
role = wxT("NO ROLE");
}
}

View File

@ -1959,7 +1959,7 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
#if wxUSE_ACCESSIBILITY
void wxWindowBase::SetAccessible(wxAccessible* accessible)
{
if (m_accessible)
if (m_accessible && (accessible != m_accessible))
delete m_accessible;
m_accessible = accessible;
if (m_accessible)
@ -2251,7 +2251,21 @@ wxAccStatus wxWindowAccessible::GetName(int childId, wxString* name)
if (!GetWindow())
return wxACC_FAIL;
wxString title(GetWindow()->GetTitle());
wxString title;
// If a child, leave wxWindows to call the function on the actual
// child object.
if (childId > 0)
return wxACC_NOT_IMPLEMENTED;
// This will eventually be replaced by specialised
// accessible classes, one for each kind of wxWindows
// control or window.
if (GetWindow()->IsKindOf(CLASSINFO(wxButton)))
title = ((wxButton*) GetWindow())->GetLabel();
else
title = GetWindow()->GetName();
if (!title.IsEmpty())
{
*name = title;
@ -2357,6 +2371,12 @@ wxAccStatus wxWindowAccessible::GetDescription(int childId, wxString* descriptio
if (!GetWindow())
return wxACC_FAIL;
wxString ht(GetWindow()->GetHelpText());
if (!ht.IsEmpty())
{
*description = ht;
return wxACC_OK;
}
return wxACC_NOT_IMPLEMENTED;
}
@ -2394,6 +2414,26 @@ wxAccStatus wxWindowAccessible::GetRole(int childId, wxAccRole* role)
if (!GetWindow())
return wxACC_FAIL;
// If a child, leave wxWindows to call the function on the actual
// child object.
if (childId > 0)
return wxACC_NOT_IMPLEMENTED;
if (GetWindow()->IsKindOf(CLASSINFO(wxControl)))
return wxACC_NOT_IMPLEMENTED;
#if wxUSE_STATUSBAR
if (GetWindow()->IsKindOf(CLASSINFO(wxStatusBar)))
return wxACC_NOT_IMPLEMENTED;
#endif
#if wxUSE_TOOLBAR
if (GetWindow()->IsKindOf(CLASSINFO(wxToolBar)))
return wxACC_NOT_IMPLEMENTED;
#endif
//*role = wxROLE_SYSTEM_CLIENT;
*role = wxROLE_SYSTEM_CLIENT;
return wxACC_OK;
return wxACC_NOT_IMPLEMENTED;
}
@ -2404,6 +2444,26 @@ wxAccStatus wxWindowAccessible::GetState(int childId, long* state)
if (!GetWindow())
return wxACC_FAIL;
// If a child, leave wxWindows to call the function on the actual
// child object.
if (childId > 0)
return wxACC_NOT_IMPLEMENTED;
if (GetWindow()->IsKindOf(CLASSINFO(wxControl)))
return wxACC_NOT_IMPLEMENTED;
#if wxUSE_STATUSBAR
if (GetWindow()->IsKindOf(CLASSINFO(wxStatusBar)))
return wxACC_NOT_IMPLEMENTED;
#endif
#if wxUSE_TOOLBAR
if (GetWindow()->IsKindOf(CLASSINFO(wxToolBar)))
return wxACC_NOT_IMPLEMENTED;
#endif
*state = 0;
return wxACC_OK;
return wxACC_NOT_IMPLEMENTED;
}

View File

@ -332,6 +332,10 @@ public:
// Call Release if this is non-NULL.
IAccessible* GetChildStdAccessible(int id);
// Gets the IAccessible interface for the given child or object.
// Call Release if this is non-NULL.
IAccessible* GetChildAccessible(int id);
private:
wxAccessible *m_pAccessible; // pointer to C++ class we belong to
@ -384,7 +388,7 @@ STDMETHODIMP wxIAccessible::accHitTest(long xLeft, long yLeft, VARIANT* pVarID)
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
return E_NOTIMPL;
else
return stdInterface->accHitTest(xLeft, yLeft, pVarID);
}
@ -401,13 +405,12 @@ STDMETHODIMP wxIAccessible::accHitTest(long xLeft, long yLeft, VARIANT* pVarID)
{
wxIAccessible* childIA = childObject->GetIAccessible();
if (!childIA)
return E_FAIL;
return E_NOTIMPL;
if (childIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarID->pdispVal) != S_OK)
return E_FAIL;
pVarID->vt = VT_DISPATCH;
// pVarID->pdispVal->AddRef();
return S_OK;
}
}
@ -423,7 +426,7 @@ STDMETHODIMP wxIAccessible::accHitTest(long xLeft, long yLeft, VARIANT* pVarID)
return S_FALSE;
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the specified object's current screen location. All visual objects must
@ -444,12 +447,22 @@ STDMETHODIMP wxIAccessible::accLocation ( long* pxLeft, long* pyTop, long* pcxWi
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
}
else
{
@ -460,7 +473,7 @@ STDMETHODIMP wxIAccessible::accLocation ( long* pxLeft, long* pyTop, long* pcxWi
return S_OK;
}
return E_FAIL;
return E_NOTIMPL;
}
// Traverses to another user interface element within a container and retrieves the object.
@ -554,12 +567,22 @@ STDMETHODIMP wxIAccessible::accNavigate ( long navDir, VARIANT varStart, VARIANT
{
wxLogDebug("Navigate not implemented");
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->accNavigate ( navDir, varStart, pVarEnd);
// Try to use child object directly.
if (varStart.vt == VT_I4 && varStart.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varStart.lVal);
if (childAccessible)
{
varStart.lVal = 0;
HRESULT hResult = childAccessible->accNavigate(navDir, varStart, pVarEnd);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accNavigate(navDir, varStart, pVarEnd);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accNavigate(navDir, varStart, pVarEnd);
}
else
{
@ -582,7 +605,6 @@ STDMETHODIMP wxIAccessible::accNavigate ( long navDir, VARIANT varStart, VARIANT
wxLogDebug("Called QueryInterface for Navigate");
pVarEnd->vt = VT_DISPATCH;
// pVarEnd->pdispVal->AddRef();
return S_OK;
}
else if (elementId > 0)
@ -601,7 +623,7 @@ STDMETHODIMP wxIAccessible::accNavigate ( long navDir, VARIANT varStart, VARIANT
}
wxLogDebug("Failing Navigate");
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the address of an IDispatch interface for the specified child.
@ -641,7 +663,7 @@ STDMETHODIMP wxIAccessible::get_accChild ( VARIANT varChildID, IDispatch** ppDis
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
return E_NOTIMPL;
else
{
wxLogDebug("Using standard interface for get_accChild");
@ -654,7 +676,7 @@ STDMETHODIMP wxIAccessible::get_accChild ( VARIANT varChildID, IDispatch** ppDis
{
wxIAccessible* objectIA = child->GetIAccessible();
if (!objectIA)
return E_FAIL;
return E_NOTIMPL;
if (objectIA->QueryInterface(IID_IDispatch, (LPVOID*) ppDispChild) != S_OK)
{
@ -662,7 +684,6 @@ STDMETHODIMP wxIAccessible::get_accChild ( VARIANT varChildID, IDispatch** ppDis
return E_FAIL;
}
// (*ppDispChild)->AddRef();
return S_OK;
}
else
@ -672,7 +693,7 @@ STDMETHODIMP wxIAccessible::get_accChild ( VARIANT varChildID, IDispatch** ppDis
}
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the number of children that belong to this object.
@ -695,7 +716,7 @@ STDMETHODIMP wxIAccessible::get_accChildCount ( long* pCountChildren)
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
return E_NOTIMPL;
else
{
wxLogDebug("Using standard interface for get_accChildCount");
@ -712,7 +733,7 @@ STDMETHODIMP wxIAccessible::get_accChildCount ( long* pCountChildren)
return S_OK;
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the IDispatch interface of the object's parent.
@ -740,7 +761,7 @@ STDMETHODIMP wxIAccessible::get_accParent ( IDispatch** ppDispParent)
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
return E_NOTIMPL;
else
return stdInterface->get_accParent (ppDispParent);
}
@ -759,17 +780,8 @@ STDMETHODIMP wxIAccessible::get_accParent ( IDispatch** ppDispParent)
return E_FAIL;
}
// (*ppDispParent)->AddRef();
wxLogDebug("Returning S_OK for get_accParent");
return S_OK;
/*
wxIAccessible* objectIA = parent->GetIAccessible();
if (!objectIA)
return E_FAIL;
objectIA->AddRef();
*ppDispParent = objectIA;
return S_OK;
*/
}
else
{
@ -781,7 +793,7 @@ STDMETHODIMP wxIAccessible::get_accParent ( IDispatch** ppDispParent)
}
}
return E_FAIL;
return E_NOTIMPL;
}
// Performs the object's default action. Not all objects have a default
@ -809,12 +821,22 @@ STDMETHODIMP wxIAccessible::accDoDefaultAction(VARIANT varID)
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->accDoDefaultAction(varID);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->accDoDefaultAction(varID);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accDoDefaultAction(varID);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accDoDefaultAction(varID);
}
return E_FAIL;
}
@ -845,12 +867,22 @@ STDMETHODIMP wxIAccessible::get_accDefaultAction ( VARIANT varID, BSTR* pszDefau
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accDefaultAction (varID, pszDefaultAction);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accDefaultAction(varID, pszDefaultAction);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDefaultAction(varID, pszDefaultAction);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDefaultAction(varID, pszDefaultAction);
}
else
{
@ -892,12 +924,22 @@ STDMETHODIMP wxIAccessible::get_accDescription ( VARIANT varID, BSTR* pszDescrip
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accDescription (varID, pszDescription);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accDescription(varID, pszDescription);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDescription(varID, pszDescription);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDescription(varID, pszDescription);
}
else
{
@ -913,7 +955,7 @@ STDMETHODIMP wxIAccessible::get_accDescription ( VARIANT varID, BSTR* pszDescrip
return S_OK;
}
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves an object's Help property string.
@ -939,12 +981,22 @@ STDMETHODIMP wxIAccessible::get_accHelp ( VARIANT varID, BSTR* pszHelp)
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accHelp (varID, pszHelp);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accHelp(varID, pszHelp);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelp(varID, pszHelp);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelp (varID, pszHelp);
}
else
{
@ -960,7 +1012,7 @@ STDMETHODIMP wxIAccessible::get_accHelp ( VARIANT varID, BSTR* pszHelp)
return S_OK;
}
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the full path of the WinHelp file associated with the specified
@ -988,14 +1040,24 @@ STDMETHODIMP wxIAccessible::get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChi
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accHelpTopic (pszHelpFile, varChild, pidTopic);
// Try to use child object directly.
if (varChild.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varChild.lVal);
if (childAccessible)
{
varChild.lVal = 0;
HRESULT hResult = childAccessible->get_accHelpTopic(pszHelpFile, varChild, pidTopic);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelpTopic(pszHelpFile, varChild, pidTopic);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelpTopic (pszHelpFile, varChild, pidTopic);
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the specified object's shortcut key or access key, also known as
@ -1024,12 +1086,22 @@ STDMETHODIMP wxIAccessible::get_accKeyboardShortcut ( VARIANT varID, BSTR* pszKe
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accKeyboardShortcut(varID, pszKeyboardShortcut);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accKeyboardShortcut(varID, pszKeyboardShortcut);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accKeyboardShortcut(varID, pszKeyboardShortcut);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accKeyboardShortcut (varID, pszKeyboardShortcut);
}
else
{
@ -1045,7 +1117,7 @@ STDMETHODIMP wxIAccessible::get_accKeyboardShortcut ( VARIANT varID, BSTR* pszKe
return S_OK;
}
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the name of the specified object.
@ -1075,25 +1147,22 @@ STDMETHODIMP wxIAccessible::get_accName ( VARIANT varID, BSTR* pszName)
if (status == wxACC_NOT_IMPLEMENTED)
{
#if 0
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accName (varID, pszName);
#endif
// Turn child reference into object reference.
IAccessible* stdInterface = GetChildStdAccessible(varID.lVal);
if (stdInterface)
// Try to use child object directly.
if (varID.lVal > 0)
{
varID.lVal = 0;
HRESULT hResult = stdInterface->get_accName(varID, pszName);
stdInterface->Release();
return hResult;
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accName(varID, pszName);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accName(varID, pszName);
}
else
return E_FAIL;
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accName (varID, pszName);
}
else
{
@ -1101,7 +1170,7 @@ STDMETHODIMP wxIAccessible::get_accName ( VARIANT varID, BSTR* pszName)
*pszName = basicString.Get();
return S_OK;
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves information that describes the role of the specified object.
@ -1131,12 +1200,22 @@ STDMETHODIMP wxIAccessible::get_accRole ( VARIANT varID, VARIANT* pVarRole)
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accRole (varID, pVarRole);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accRole(varID, pVarRole);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accRole(varID, pVarRole);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accRole (varID, pVarRole);
}
else
{
@ -1151,7 +1230,7 @@ STDMETHODIMP wxIAccessible::get_accRole ( VARIANT varID, VARIANT* pVarRole)
return S_OK;
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the current state of the specified object.
@ -1164,7 +1243,7 @@ STDMETHODIMP wxIAccessible::get_accState ( VARIANT varID, VARIANT* pVarState)
if (!m_pAccessible)
return E_FAIL;
if (varID.vt != VT_I4)
if (varID.vt != VT_I4 && varID.vt != VT_EMPTY)
{
wxLogDebug("Invalid arg for get_accState");
return E_INVALIDARG;
@ -1178,12 +1257,22 @@ STDMETHODIMP wxIAccessible::get_accState ( VARIANT varID, VARIANT* pVarState)
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accState (varID, pVarState);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accState(varID, pVarState);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accState(varID, pVarState);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accState (varID, pVarState);
}
else
{
@ -1192,7 +1281,7 @@ STDMETHODIMP wxIAccessible::get_accState ( VARIANT varID, VARIANT* pVarState)
pVarState->vt = VT_I4;
return S_OK;
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the value of the specified object.
@ -1220,12 +1309,22 @@ STDMETHODIMP wxIAccessible::get_accValue ( VARIANT varID, BSTR* pszValue)
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->get_accValue (varID, pszValue);
// Try to use child object directly.
if (varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->get_accValue(varID, pszValue);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accValue(varID, pszValue);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accValue (varID, pszValue);
}
else
{
@ -1233,7 +1332,7 @@ STDMETHODIMP wxIAccessible::get_accValue ( VARIANT varID, BSTR* pszValue)
* pszValue = basicString.Get();
return S_OK;
}
return E_FAIL;
return E_NOTIMPL;
}
// Modifies the selection or moves the keyboard focus of the
@ -1261,17 +1360,27 @@ STDMETHODIMP wxIAccessible::accSelect ( long flagsSelect, VARIANT varID )
if (status == wxACC_NOT_IMPLEMENTED)
{
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
else
return stdInterface->accSelect ( flagsSelect, varID );
// Try to use child object directly.
if (varID.lVal > 0 && varID.lVal > 0)
{
IAccessible* childAccessible = GetChildAccessible(varID.lVal);
if (childAccessible)
{
varID.lVal = 0;
HRESULT hResult = childAccessible->accSelect(flagsSelect, varID);
childAccessible->Release();
return hResult;
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accSelect(flagsSelect, varID);
}
else if (m_pAccessible->GetIAccessibleStd())
return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accSelect(flagsSelect, varID);
}
else
return S_OK;
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the object that has the keyboard focus. All objects
@ -1297,7 +1406,7 @@ STDMETHODIMP wxIAccessible::get_accFocus ( VARIANT* pVarID)
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
return E_NOTIMPL;
else
return stdInterface->get_accFocus (pVarID);
}
@ -1312,13 +1421,12 @@ STDMETHODIMP wxIAccessible::get_accFocus ( VARIANT* pVarID)
{
wxIAccessible* childIA = childObject->GetIAccessible();
if (!childIA)
return E_FAIL;
return E_NOTIMPL;
if (childIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarID->pdispVal) != S_OK)
return E_FAIL;
pVarID->vt = VT_DISPATCH;
// pVarID->pdispVal->AddRef();
return S_OK;
}
}
@ -1334,7 +1442,7 @@ STDMETHODIMP wxIAccessible::get_accFocus ( VARIANT* pVarID)
return S_FALSE;
}
return E_FAIL;
return E_NOTIMPL;
}
// Retrieves the selected children of this object. All objects
@ -1359,7 +1467,7 @@ STDMETHODIMP wxIAccessible::get_accSelection ( VARIANT * pVarChildren)
// Use standard interface instead.
IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
if (!stdInterface)
return E_FAIL;
return E_NOTIMPL;
else
return stdInterface->get_accSelection (pVarChildren);
}
@ -1377,13 +1485,12 @@ STDMETHODIMP wxIAccessible::get_accSelection ( VARIANT * pVarChildren)
wxAccessible* childObject = (wxAccessible*) selections.GetVoidPtr();
wxIAccessible* childIA = childObject->GetIAccessible();
if (!childIA)
return E_FAIL;
return E_NOTIMPL;
if (childIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarChildren->pdispVal) != S_OK)
return E_FAIL;
pVarChildren->vt = VT_DISPATCH;
// pVarChildren->pdispVal->AddRef();
return S_OK;
}
@ -1401,7 +1508,7 @@ STDMETHODIMP wxIAccessible::get_accSelection ( VARIANT * pVarChildren)
}
}
return E_FAIL;
return E_NOTIMPL;
}
// Get type info
@ -1438,7 +1545,7 @@ STDMETHODIMP wxIAccessible::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
return E_NOTIMPL;
}
// Gets the IAccessible interface for the given child or object.
// Gets the standard IAccessible interface for the given child or object.
// Call Release if this is non-NULL.
IAccessible* wxIAccessible::GetChildStdAccessible(int id)
{
@ -1516,6 +1623,40 @@ IAccessible* wxIAccessible::GetChildStdAccessible(int id)
return NULL;
}
// Gets the IAccessible interface for the given child or object.
// Call Release if this is non-NULL.
IAccessible* wxIAccessible::GetChildAccessible(int id)
{
if (id == 0)
{
IAccessible* obj = this;
obj->AddRef();
return obj;
}
else
{
VARIANT var;
VariantInit(& var);
var.vt = VT_I4;
var.lVal = id;
IDispatch* pDispatch = NULL;
if (S_OK == get_accChild ( var, & pDispatch))
{
IAccessible* childAccessible = NULL;
if (pDispatch->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
{
pDispatch->Release();
return childAccessible;
}
else
{
pDispatch->Release();
}
}
}
return NULL;
}
// ----------------------------------------------------------------------------
// wxAccessible implementation
@ -1552,13 +1693,8 @@ void* wxAccessible::GetIAccessibleStd()
if (GetWindow())
{
#if 0
HRESULT retCode = ::CreateStdAccessibleProxy((HWND) GetWindow()->GetHWND(),
wxT("wxWindowClass"), OBJID_CLIENT, IID_IAccessible, (void**) & m_pIAccessibleStd);
#else
HRESULT retCode = ::CreateStdAccessibleObject((HWND) GetWindow()->GetHWND(),
OBJID_CLIENT, IID_IAccessible, (void**) & m_pIAccessibleStd);
#endif
if (retCode == S_OK)
return m_pIAccessibleStd;
else