summaryrefslogtreecommitdiff
path: root/winaccessibility/source/service/AccObjectWinManager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'winaccessibility/source/service/AccObjectWinManager.cxx')
-rw-r--r--winaccessibility/source/service/AccObjectWinManager.cxx1321
1 files changed, 1321 insertions, 0 deletions
diff --git a/winaccessibility/source/service/AccObjectWinManager.cxx b/winaccessibility/source/service/AccObjectWinManager.cxx
new file mode 100644
index 000000000000..08ed3efd2b43
--- /dev/null
+++ b/winaccessibility/source/service/AccObjectWinManager.cxx
@@ -0,0 +1,1321 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include <cassert>
+
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+#include <oleacc.h>
+#ifndef _SV_AccObjectWinManager_HXX
+#include "AccObjectWinManager.hxx"
+#endif
+#include "AccEventListener.hxx"
+#include "AccComponentEventListener.hxx"
+#include "AccContainerEventListener.hxx"
+#include "AccDialogEventListener.hxx"
+#include "AccWindowEventListener.hxx"
+#include "AccFrameEventListener.hxx"
+#include "AccMenuEventListener.hxx"
+#include "AccObjectContainerEventListener.hxx"
+#include "AccParagraphEventListener.hxx"
+#include "AccTextComponentEventListener.hxx"
+#include "AccListEventListener.hxx"
+#include "AccTreeEventListener.hxx"
+#include "AccTableEventListener.hxx"
+#include "AccObject.hxx"
+#include "unomsaaevent.hxx"
+#include "checkmt.hxx"
+
+#define CHILDID_SELF 0
+
+
+using namespace std;
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+AccObjectWinManager* g_acc_manager = NULL;
+AccObjectWinManager* AccObjectWinManager::me = NULL;
+
+/**
+ * Implementation of interface XMSAAService's method getAccObjectPtr() that return the
+ * corresponding com interface with the MS event.
+ *
+ * @param
+ * @return Com interface.
+ */
+long GetMSComPtr(long hWnd, long lParam, long wParam)
+{
+ if( g_acc_manager )
+ return (long)g_acc_manager->Get_ToATInterface(HWND((void*)hWnd),lParam,wParam );
+ return NULL;
+}
+
+/**
+ * constructor
+ * @param Agent The agent kept in all listeners,it's the sole interface by which
+ * listener communicate with windows manager.
+ * pEventAccObj The present event accobject.
+ * oldFocus Last focused object.
+ * isSelectionChanged flag that identifies if there is selection changed.
+ * selectionChildObj Selected object.
+ * dChildID Chile resource ID.
+ * hAcc TopWindowHWND
+ * @return
+ */
+AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ):
+ pAgent( Agent ),
+ oldFocus( NULL )
+{
+}
+
+/**
+ * Public method to produce manager
+ * @param Agent The agent kept in all listeners,it's the sole interface by which
+ * listener communicate with windows manager.
+ * @return
+ */
+AccObjectWinManager* AccObjectWinManager::CreateAccObjectWinManagerInstance( AccObjectManagerAgent* Agent )
+{
+ if( me == NULL )
+ {
+ me = new AccObjectWinManager( Agent );
+ g_acc_manager = me;
+ return me;
+ }
+
+ return me;
+}
+
+
+/**
+ * Destructor,clear all resource.
+ * @param
+ * @return
+ */
+AccObjectWinManager::~AccObjectWinManager()
+{
+ XIdAccList.clear();
+ HwndXAcc.clear();
+ XResIdAccList.clear();
+ XHWNDDocList.clear();
+#ifdef ACC_DEBUG
+
+ fclose( pFile );
+#endif
+}
+
+
+/**
+ * Get valid com object interface when notifying some MSAA event
+ * @param pWND The top window handle that contains that event control.
+ * @param wParam Windows system interface.
+ * @return Com interface with event.
+ */
+
+long AccObjectWinManager::Get_ToATInterface( HWND hWnd, long lParam, long wParam)
+{
+ vos::OGuard localGuard(maATInterfaceMutex);//
+
+ IMAccessible* pRetIMAcc = NULL;
+
+ if(lParam == OBJID_CLIENT )
+ {
+ AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd);
+ if(topWindowAccObj)
+ {
+ pRetIMAcc = topWindowAccObj->GetIMAccessible();
+ if(pRetIMAcc)
+ pRetIMAcc->AddRef();//increase COM reference count
+ }
+ }
+
+ if ( pRetIMAcc && lParam == OBJID_CLIENT )
+ {
+ IAccessible* pTemp = dynamic_cast<IAccessible*>( pRetIMAcc );
+ HRESULT result = LresultFromObject(IID_IAccessible, wParam, pTemp);
+ pTemp->Release();
+ return result;
+ }
+ return 0;
+}
+
+/**
+ * Search AccObject by XAccessible pointer from our container.
+ * @param pXAcc XAccessible interface.
+ * @return Pointer of accObject that is found.
+ */
+AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc)
+{
+ if( pXAcc == NULL)
+ return NULL;
+
+ XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
+ if ( pIndTemp == XIdAccList.end() )
+ return NULL;
+
+ return &(pIndTemp->second);
+}
+
+/**
+ * Search XAccessible by AccObject pointer from our container.
+ * @param pAccObj AccObject pointer.
+ * @return Pointer of XAccessible Interface.
+ */
+XAccessible* AccObjectWinManager::GetXAccByAccObj(AccObject* pAccObj)
+{
+ XIdToAccObjHash::iterator iter = XIdAccList.begin();
+ while(iter!=XIdAccList.end())
+ {
+ AccObject* tmp = &(iter->second);
+ if(tmp== pAccObj)
+ return (XAccessible*)(iter->first);
+ iter++;
+ }
+ return NULL;
+}
+
+/**
+ * get acc object of top window by its handle
+ * @param hWnd, top window handle
+ * @return pointer to AccObject
+ */
+AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd)
+{
+ XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
+ if(iterResult == HwndXAcc.end())
+ return NULL;
+ XAccessible* pXAcc = (XAccessible*)(iterResult->second);
+ return GetAccObjByXAcc(pXAcc);
+}
+
+/**
+ * Simulate MSAA event via XAccessible interface and event type.
+ * @param pXAcc XAccessible interface.
+ * @param state Customize Interface
+ * @return The terminate result that identifies if the call is successful.
+ */
+sal_Bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc,short state)
+{
+ vos::OGuard aGuard(aNotifyMutex);
+
+ if (!IsInMainThread())
+ {
+ return sal_False;
+ }
+
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+
+ AccObject* selfAccObj= GetAccObjByXAcc(pXAcc);
+
+ if(selfAccObj==NULL)
+ return sal_False;
+
+ int selectNum =0;
+
+ long dChildID = selfAccObj->GetResID();
+ HWND hAcc = selfAccObj->GetParentHWND();
+
+ switch(state)
+ {
+ case UM_EVENT_STATE_FOCUSED:
+ {
+ UpdateAccFocus(pXAcc);
+ if( selfAccObj )
+ selfAccObj->UpdateDefaultAction( );
+ UpdateValue(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ }
+ case UM_EVENT_STATE_BUSY:
+ NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_STATE_CHECKED:
+ NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_STATE_PRESSED:
+ NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+
+ //Removed fire out selected event
+ //case UM_EVENT_STATE_SELECTED:
+ // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ // break;
+ case UM_EVENT_STATE_ARMED:
+ UpdateAccFocus(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENU_START:
+ NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENU_END:
+ NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENUPOPUPSTART:
+ NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENUPOPUPEND:
+ NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED:
+ NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED_ADD:
+ NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED_REMOVE:
+ NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED_WITHIN:
+ NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_VALUECHANGE:
+ UpdateValue(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_NAMECHANGE:
+ NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_DESCRIPTIONCHANGE:
+ NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_DEFACTIONCHANGE:
+ NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_CARETCHANGE:
+ NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_TEXTCHANGE:
+ NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_ACTIVE_DESCENDANT_CHANGED:
+ UpdateAccFocus(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_BOUNDRECT_CHANGED:
+ NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_VISIBLE_DATA_CHANGED:
+ NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SHOW :
+ NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID );
+ NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_CAPTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_MODEL_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_ROW_HEADER_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_SUMMARY_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_REORDER:
+ NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_PAGE_CHANGED:
+ NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_CHILD_REMOVED:
+ NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_CHILD_ADDED:
+ NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_PAGECHANGED:
+ NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TEXT_SELECTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SECTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_COLUMN_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ default:
+ break;
+ }
+
+ return sal_True;
+}
+
+/**
+ * Get Parent XAccessible interface by XAccessible interface.
+ * @param pXAcc XAccessible interface.
+ * @return Parent XAccessible interface.
+ */
+XAccessible* AccObjectWinManager::GetParentXAccessible( XAccessible* pXAcc )
+{
+ AccObject* pObj= GetAccObjByXAcc(pXAcc);
+ if( pObj ==NULL )
+ return NULL;
+ if(pObj->GetParentObj())
+ {
+ pObj = pObj->GetParentObj();
+ return pObj->GetXAccessible().get();
+ }
+ return NULL;
+}
+
+/**
+ * Get Parent role by XAccessible interface.
+ * @param pXAcc XAccessible interface.
+ * @return Parent role.
+ */
+short AccObjectWinManager::GetParentRole( XAccessible* pXAcc )
+{
+ AccObject* pObj= GetAccObjByXAcc(pXAcc);
+ if( pObj ==NULL )
+ return -1;
+ if(pObj->GetParentObj())
+ {
+ pObj = pObj->GetParentObj();
+ if(pObj->GetXAccessible().is())
+ {
+ XAccessible* pXAcc = pObj->GetXAccessible().get();
+ Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
+ if(pRContext.is())
+ return pRContext->getAccessibleRole();
+ }
+ }
+ return -1;
+}
+
+/**
+ * Update focus objcet by new focused XAccessible interface.
+ * @param newFocus New XAccessible interface that gets focus.
+ * @return
+ */
+void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus)
+{
+ AccObject* pAccObjNew = GetAccObjByXAcc(newFocus);
+ if(pAccObjNew)
+ {
+ AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus);
+ oldFocus = newFocus;
+ pAccObjNew->setFocus();
+ //if old == new, the pAccObjNew will be without focused state
+ if (pAccObjOld && pAccObjOld != pAccObjNew)
+ pAccObjOld->unsetFocus();
+ }
+}
+
+/**
+ * Update selected objcet by new focused XAccessible interface.
+ * @param pXAcc XAccessible interface that has selected child changed.
+ * @return Selected children count.
+ */
+int AccObjectWinManager::UpdateAccSelection(XAccessible* pXAcc)
+{
+ XAccessibleSelection* pSelection = NULL;
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+ Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
+ if( !pRSelection.is() )
+ return sal_False;
+
+ AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
+ if(pAccObj==NULL)
+ return sal_False;
+
+ Reference<XAccessible> pRChild = NULL;
+ AccObject* pAccChildObj = NULL;
+ int selectNum= pRSelection->getSelectedAccessibleChildCount();
+
+ IAccSelectionList oldSelection = pAccObj->GetSelection();
+
+ if(selectNum > 4)//for selected.
+ return selectNum;
+ if(selectNum == 1 && oldSelection.size() == 0)
+ return 1;
+
+ for (int i=0;i<selectNum;i++)
+ {
+ pRChild = pRSelection->getSelectedAccessibleChild(i);
+ if(!pRChild.is())
+ {
+ continue;
+ }
+ Reference<XAccessibleContext> pRChildContext = pRChild->getAccessibleContext();
+ if(!pRChildContext.is())
+ {
+ continue;
+ }
+ long index = pRChildContext->getAccessibleIndexInParent();
+ IAccSelectionList::iterator temp = oldSelection.find(index);
+ if ( temp != oldSelection.end() )
+ {
+ oldSelection.erase(index);
+ continue;
+ }
+
+ pAccChildObj = NULL;
+ pAccChildObj = GetAccObjByXAcc(pRChild.get());
+ if(!pAccChildObj)
+ {
+ InsertAccObj(pRChild.get(), pXAcc,pAccObj->GetParentHWND());
+ pAccChildObj = GetAccObjByXAcc(pRChild.get());
+ }
+
+ pAccObj->AddSelect(index, pAccChildObj);
+
+ if(pAccChildObj != NULL)
+ NotifyWinEvent(EVENT_OBJECT_SELECTIONADD,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
+ }
+
+ IAccSelectionList::iterator iter = oldSelection.begin();
+ while(iter!=oldSelection.end())
+ {
+ pAccObj->GetSelection().erase(iter->first);
+ pAccChildObj = (AccObject*)(iter->second);
+ if(pAccChildObj != NULL)
+ NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
+ iter++;
+ }
+ return 0;
+
+}
+
+/**
+ * Delete child element from children list.
+ * @param pObj Child element that should be removed from parant child list.
+ * @return
+ */
+void AccObjectWinManager::DeleteAccChildNode( AccObject* pObj )
+{
+ AccObject *parentAccObj = pObj->GetParentObj();
+ if( parentAccObj )
+ parentAccObj->DeleteChild( pObj );
+}
+
+/**
+ * Delete XAccessible items in top window handle hashtable
+ * @param pXAcc XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible* pXAcc )
+{
+ XHWNDToXAccHash::iterator iter = HwndXAcc.begin();
+ while(iter!=HwndXAcc.end())
+ {
+ if(iter->second == pXAcc )
+ {
+ HwndXAcc.erase(iter);
+ return;
+ }
+ iter++;
+ }
+}
+
+/**
+ * Delete Delete all children with the tree root of XAccessible pointer
+ * @param pXAcc Tree root XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::DeleteChildrenAccObj(XAccessible* pXAcc)
+{
+ vos::OGuard aGuard( aDeleteMutex );
+ AccObject* currentObj=NULL;
+ AccObject* childObj=NULL;
+ XAccessible* pTmpXAcc=NULL;
+
+ currentObj = GetAccObjByXAcc( pXAcc);
+ if(currentObj)
+ {
+ childObj = currentObj->NextChild();
+ while(childObj)
+ {
+ pTmpXAcc = GetXAccByAccObj(childObj);
+ if(pTmpXAcc)
+ {
+ DeleteChildrenAccObj(pTmpXAcc);
+ DeleteAccObj(pTmpXAcc);
+ }
+ childObj = currentObj->NextChild();
+ }
+ }
+}
+
+/**
+ * Delete Delete Acc object self.
+ * @param pXAcc The XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
+{
+ vos::OGuard aGuard( aDeleteMutex );
+ if( pXAcc == NULL )
+ return;
+ XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
+ if( temp != XIdAccList.end() )
+ {
+ ResIdGen.SetSub( temp->second.GetResID() );
+ }
+ else
+ {
+ return;
+ }
+
+ AccObject& accObj = temp->second;
+ DeleteAccChildNode( &accObj );
+ DeleteAccListener( &accObj );
+ if( accObj.GetIMAccessible() )
+ {
+ accObj.GetIMAccessible()->Release();
+ }
+ XIdAccList.erase( pXAcc );
+ XResIdAccList.erase( accObj.GetResID() );
+ DeleteFromHwndXAcc(pXAcc);
+}
+
+/**
+ * Delete listener that inspects some XAccessible object
+ * @param pAccObj Accobject pointer.
+ * @return
+ */
+void AccObjectWinManager::DeleteAccListener( AccObject* pAccObj )
+{
+ AccEventListener* listener = pAccObj->getListener();
+ if( listener==NULL )
+ return;
+ listener->removeMeFromBroadcaster();
+ pAccObj->SetListener(NULL);
+}
+
+/**
+ * Generate a child ID, which is used for AT
+ * @param
+ * @return New resource ID.
+ */
+inline long AccObjectWinManager::ImpleGenerateResID()
+{
+ return ResIdGen.GenerateNewResID();
+}
+
+/**
+ * Insert all children of the current acc object
+ * @param pXAcc XAccessible interface
+ * @param pWnd Top Window handle
+ * @return The calling result.
+ */
+sal_Bool AccObjectWinManager::InsertChildrenAccObj( com::sun::star::accessibility::XAccessible* pXAcc,
+ HWND pWnd)
+{
+ if(!IsContainer(pXAcc))
+ return sal_False;
+
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+ short role = pRContext->getAccessibleRole();
+
+ if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role )
+ {
+ if(IsStateManageDescendant(pXAcc))
+ {
+ return sal_True;
+ }
+ }
+
+ int count = pRContext->getAccessibleChildCount();
+ for (int i=0;i<count;i++)
+ {
+ Reference<XAccessible> mxAccessible
+ = pRContext->getAccessibleChild(i);
+ XAccessible* mpAccessible = mxAccessible.get();
+ if(mpAccessible != NULL)
+ {
+ InsertAccObj( mpAccessible,pXAcc,pWnd );
+ InsertChildrenAccObj(mpAccessible,pWnd);
+ }
+ }
+
+ return sal_True;
+}
+
+/**
+ * Insert child object.
+ * @param pCurObj The child object
+ * @param pParentObj The parant object
+ * @param pWnd Top window handle.
+ * @return
+ */
+void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pParentObj, HWND /* pWnd */ )
+{
+ if(pCurObj)
+ {
+ if(pParentObj)
+ {
+ pParentObj->InsertChild(pCurObj);
+ }
+ else
+ {
+ pCurObj->UpdateValidWindow();
+ }
+ }
+}
+
+/**
+ * Insert child object.
+ * @param pCurObj The child object
+ * @param pParentObj The parant object
+ * @param pWnd Top window handle.
+ * @return
+ */
+sal_Bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd )
+{
+ XIdToAccObjHash::iterator itXacc = XIdAccList.find( (void*)pXAcc );
+ if (itXacc != XIdAccList.end() )
+ {
+ short nCurRole =GetRole(pXAcc);
+ if (AccessibleRole::SHAPE == nCurRole)
+ {
+ AccObject &objXacc = itXacc->second;
+ AccObject *pObjParent = objXacc.GetParentObj();
+ if (pObjParent &&
+ pObjParent->GetXAccessible().is() &&
+ pObjParent->GetXAccessible().get() != pParentXAcc)
+ {
+ XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( (void*)pParentXAcc );
+ if(itXaccParent != XIdAccList.end())
+ {
+ objXacc.SetParentObj(&(itXaccParent->second));
+ }
+ }
+ }
+ return sal_False;
+ }
+
+
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+ if( pWnd == NULL )
+ {
+ if(pParentXAcc)
+ {
+ AccObject* pObj = GetAccObjByXAcc(pParentXAcc);
+ if(pObj)
+ pWnd = pObj->GetParentHWND();
+ }
+ if( pWnd == NULL )
+ return sal_False;
+ }
+
+ AccObject pObj( pXAcc,pAgent );
+ if( pObj.GetIMAccessible() == NULL )
+ return sal_False;
+ pObj.SetResID( this->ImpleGenerateResID());
+ pObj.SetParentHWND( pWnd );
+
+ //for file name support
+ if ( pObj.GetRole() == DOCUMENT )
+ {
+ XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find( (long)pWnd );
+ if ( aIter != XHWNDDocList.end() )
+ {
+ XHWNDDocList.erase( aIter );
+ }
+ XHWNDDocList.insert( XHWNDToDocumentHash::value_type( (long)pWnd, pXAcc ) );
+
+ }
+ //end of file name
+
+ AccEventListener* listener = createAccEventListener(pXAcc, pAgent);
+ if(listener==NULL)
+ return sal_False;
+ Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
+ Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
+ if (broadcaster.is())
+ {
+ Reference <XAccessibleEventListener> pp (
+ static_cast< XAccessibleEventListener* >(listener),UNO_QUERY );
+ if(pp.is())
+ {
+ broadcaster->addEventListener(pp);
+ }
+ else
+ {
+ delete listener;
+ return sal_False;
+ }
+ }
+ else
+ return sal_False;
+
+ XIdAccList.insert( XIdToAccObjHash::value_type( (void*)pXAcc, pObj ));
+ XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
+ XResIdAccList.insert(XResIdToAccObjHash::value_type(pObj.GetResID(),&(pIndTemp->second)));
+
+ AccObject* pCurObj = GetAccObjByXAcc(pXAcc);
+ if( pCurObj )
+ {
+ pCurObj->SetListener( listener );
+ if(listener != NULL)
+ listener->acquire();
+ }
+
+ AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc);
+ InsertAccChildNode(pCurObj,pParentObj,pWnd);
+ if( pCurObj )
+ pCurObj->UpdateAccessibleInfoFromUnoToMSAA();
+ return sal_True;
+}
+
+
+/**
+ * save the pair <topwindowhandle, XAccessible>
+ * @param hWnd, top window handle
+ * @param pXAcc XAccessible interface for top window
+ * @return void
+ */
+void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ HwndXAcc.insert( XHWNDToXAccHash::value_type( hWnd,(void*)pXAcc ) );
+}
+
+
+/**
+ * create the corresponding listener.
+ * @param pXAcc XAccessible interface.
+ * @param Agent The agent kept in all listeners,it's the sole interface by which
+ * listener communicate with windows manager.
+ * @return
+ */
+AccEventListener* AccObjectWinManager::createAccEventListener(XAccessible* pXAcc, AccObjectManagerAgent* /* Agent */ )
+{
+ AccEventListener* listener = NULL;
+ Reference<XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
+ if(xContext.is())
+ {
+ switch( xContext->getAccessibleRole() )
+ {
+ case /*AccessibleRole::*/DIALOG:
+ listener = new AccDialogEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/FRAME:
+ listener = new AccFrameEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/WINDOW:
+ listener = new AccWindowEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/ROOT_PANE:
+ listener = new AccFrameEventListener(pXAcc,pAgent);
+ break;
+ //Container
+ case /*AccessibleRole::*/CANVAS:
+ case /*AccessibleRole::*/COMBO_BOX:
+ case /*AccessibleRole::*/DOCUMENT:
+ case /*AccessibleRole::*/END_NOTE:
+ case /*AccessibleRole::*/FILLER:
+ case /*AccessibleRole::*/FOOTNOTE:
+ case /*AccessibleRole::*/FOOTER:
+ case /*AccessibleRole::*/HEADER:
+ case /*AccessibleRole::*/LAYERED_PANE:
+ case /*AccessibleRole::*/MENU_BAR:
+ case /*AccessibleRole::*/POPUP_MENU:
+ case /*AccessibleRole::*/OPTION_PANE:
+ case /*AccessibleRole::*/PAGE_TAB:
+ case /*AccessibleRole::*/PAGE_TAB_LIST:
+ case /*AccessibleRole::*/PANEL:
+ case /*AccessibleRole::*/SCROLL_PANE:
+ case /*AccessibleRole::*/SPLIT_PANE:
+ case /*AccessibleRole::*/STATUS_BAR:
+ case /*AccessibleRole::*/TABLE_CELL:
+ case /*AccessibleRole::*/TOOL_BAR:
+ case /*AccessibleRole::*/VIEW_PORT:
+ listener = new AccContainerEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/PARAGRAPH:
+ case /*AccessibleRole::*/HEADING:
+ listener = new AccParagraphEventListener(pXAcc,pAgent);
+ break;
+ //Component
+ case /*AccessibleRole::*/CHECK_BOX:
+ case /*AccessibleRole::*/ICON:
+ case /*AccessibleRole::*/LABEL:
+ case /*AccessibleRole::*/MENU_ITEM:
+ case /*AccessibleRole::*/CHECK_MENU_ITEM:
+ case /*AccessibleRole::*/RADIO_MENU_ITEM:
+ case /*AccessibleRole::*/PUSH_BUTTON:
+ case /*AccessibleRole::*/RADIO_BUTTON:
+ case /*AccessibleRole::*/SCROLL_BAR:
+ case /*AccessibleRole::*/SEPARATOR:
+ case /*AccessibleRole::*/TOGGLE_BUTTON:
+ case /*AccessibleRole::*/BUTTON_DROPDOWN:
+ case /*AccessibleRole::*/TOOL_TIP:
+ case /*AccessibleRole::*/SPIN_BOX:
+ case DATE_EDITOR:
+ listener = new AccComponentEventListener(pXAcc,pAgent);
+ break;
+ //text component
+ case /*AccessibleRole::*/TEXT:
+ listener = new AccTextComponentEventListener(pXAcc,pAgent);
+ break;
+ //menu
+ case /*AccessibleRole::*/MENU:
+ listener = new AccMenuEventListener(pXAcc,pAgent);
+ break;
+ //object container
+ case /*AccessibleRole::*/SHAPE:
+
+ case /*AccessibleRole::*/EMBEDDED_OBJECT:
+ case /*AccessibleRole::*/GRAPHIC:
+ case /*AccessibleRole::*/TEXT_FRAME:
+ listener = new AccObjectContainerEventListener(pXAcc,pAgent);
+ break;
+ //descendmanager
+ case /*AccessibleRole::*/LIST:
+ listener = new AccListEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/TREE:
+ listener = new AccTreeEventListener(pXAcc,pAgent);
+ break;
+ //special
+ case /*AccessibleRole::*/COLUMN_HEADER:
+ case /*AccessibleRole::*/TABLE:
+ listener = new AccTableEventListener(pXAcc,pAgent);
+ break;
+ default:
+ listener = new AccContainerEventListener(pXAcc,pAgent);
+ break;
+ }
+ }
+
+ return listener;
+}
+
+/**
+ * state is a combination integer, each bit of which represents a single state,
+ * such as focused,1 for the state on,0 for the state off. Here call COM interface
+ * to modify the state value, including DecreaseState.
+ * @param pXAcc XAccessible interface.
+ * @param pState Changed state.
+ * @return
+ */
+void AccObjectWinManager::DecreaseState( XAccessible* pXAcc,unsigned short pState )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->DecreaseState( pState );
+}
+
+/**
+ * state is a combination integer, each bit of which represents a single state,such as focused,1 for
+ * the state on,0 for the state off. Here call COM interface to modify the state value, including
+ * IncreaseState.
+ * @param pXAcc XAccessible interface.
+ * @param pState Changed state.
+ * @return
+ */
+void AccObjectWinManager::IncreaseState( XAccessible* pXAcc,unsigned short pState )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->IncreaseState( pState );
+}
+
+void AccObjectWinManager::UpdateState( com::sun::star::accessibility::XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->UpdateState( );
+}
+
+/**
+ * Set corresponding com object's accessible name via XAccessilbe interface and new
+ * name
+ * @param pXAcc XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::UpdateAccName( XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->UpdateName();
+}
+
+void AccObjectWinManager::UpdateAction( XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->UpdateAction();
+}
+
+void AccObjectWinManager::UpdateDescription( XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if ( pAccObj )
+ pAccObj->UpdateDescription();
+}
+
+/**
+ * Set corresponding com object's accessible location via XAccessilbe interface and new
+ * location.
+ * @param pXAcc XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::SetLocation( XAccessible* pXAcc, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
+{
+ AccObject* pObj = GetAccObjByXAcc( pXAcc );
+ //get the location from XComponent.
+ Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
+ if( pObj )
+ pObj->UpdateLocation();
+}
+
+/**
+ * Set corresponding com object's value via XAccessilbe interface and new value.
+ * @param pXAcc XAccessible interface.
+ * @param pAny new value.
+ * @return
+ */
+void AccObjectWinManager::SetValue( XAccessible* pXAcc, Any pAny )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->SetValue( pAny );
+}
+
+/**
+ * Set corresponding com object's value via XAccessilbe interface.
+ * @param pXAcc XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::UpdateValue( XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->UpdateValue();
+}
+
+/**
+ * Set corresponding com object's name via XAccessilbe interface and new name.
+ * @param pXAcc XAccessible interface.
+ * @param newName new name
+ * @return
+ */
+void AccObjectWinManager::SetAccName( XAccessible* pXAcc, Any newName)
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->SetName( newName );
+}
+
+/**
+ * Set corresponding com object's description via XAccessilbe interface and new description.
+ * @param pXAcc XAccessible interface.
+ * @param newDesc new description
+ * @return
+ */
+void AccObjectWinManager::SetDescription( XAccessible* pXAcc, Any newDesc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->SetDescription( newDesc );
+}
+
+/**
+ * Set corresponding com object's role via XAccessilbe interface and new role.
+ * @param pXAcc XAccessible interface.
+ * @param Role new role
+ * @return
+ */
+void AccObjectWinManager::SetRole( XAccessible* pXAcc, long Role )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->SetRole( (short)Role );
+}
+
+/**
+ * Judge if a XAccessible object is a container object.
+ * @param pAccessible XAccessible interface.
+ * @return If XAccessible object is container.
+ */
+sal_Bool AccObjectWinManager::IsContainer(XAccessible* pAccessible)
+{
+ try
+ {
+ if(pAccessible)
+ {
+ Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(xContext.is())
+ {
+ switch( xContext->getAccessibleRole() )
+ {
+ case /*AccessibleRole::*/DIALOG:
+ case /*AccessibleRole::*/FRAME:
+ case /*AccessibleRole::*/WINDOW:
+ case /*AccessibleRole::*/ROOT_PANE:
+ case /*AccessibleRole::*/CANVAS:
+ case /*AccessibleRole::*/COMBO_BOX:
+ case /*AccessibleRole::*/DOCUMENT:
+ case /*AccessibleRole::*/EMBEDDED_OBJECT:
+ case /*AccessibleRole::*/END_NOTE:
+ case /*AccessibleRole::*/FILLER:
+ case /*AccessibleRole::*/FOOTNOTE:
+ case /*AccessibleRole::*/FOOTER:
+ case /*AccessibleRole::*/GRAPHIC:
+ case /*AccessibleRole::*/GROUP_BOX:
+ case /*AccessibleRole::*/HEADER:
+ case /*AccessibleRole::*/LAYERED_PANE:
+ case /*AccessibleRole::*/MENU_BAR:
+ case /*AccessibleRole::*/POPUP_MENU:
+ case /*AccessibleRole::*/OPTION_PANE:
+ case /*AccessibleRole::*/PAGE_TAB:
+ case /*AccessibleRole::*/PAGE_TAB_LIST:
+ case /*AccessibleRole::*/PANEL:
+ case /*AccessibleRole::*/SCROLL_PANE:
+ case /*AccessibleRole::*/SPLIT_PANE:
+ case /*AccessibleRole::*/STATUS_BAR:
+ case /*AccessibleRole::*/TABLE_CELL:
+ case /*AccessibleRole::*/TEXT_FRAME:
+ case /*AccessibleRole::*/TOOL_BAR:
+ case /*AccessibleRole::*/VIEW_PORT:
+ case /*AccessibleRole::*/SHAPE:
+ return sal_True;
+ break;
+ case /*AccessibleRole::*/COLUMN_HEADER:
+ case /*AccessibleRole::*/TABLE:
+ if(!IsStateManageDescendant(pAccessible))
+ return sal_True;
+ break;
+ case /*AccessibleRole::*/MENU:
+ return sal_True;
+ break;
+ default:
+ return sal_False;
+ }
+ }
+ }
+ }
+ catch(...)
+ {
+ return sal_False;
+ }
+ return sal_False;
+}
+
+/**
+ * Judge if a XAccessible object has ManageDescendant event.
+ * @param pAccessible XAccessible interface.
+ * @return If XAccessible object is managedescendant.
+ */
+bool AccObjectWinManager::IsStateManageDescendant(XAccessible* pAccessible)
+{
+ if(pAccessible)
+ {
+ Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(xContext.is())
+ {
+ Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
+ if( !pRState.is() )
+ return sal_False;
+
+ Sequence<short> pStates = pRState->getStates();
+ int count = pStates.getLength();
+ for( int iIndex = 0;iIndex < count;iIndex++ )
+ {
+ if(pStates[iIndex] == /*AccessibleStateType::*/MANAGES_DESCENDANTS)
+ return sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+/**
+ * Query and get IAccessible interface by XAccessible interface from list.
+ * @param pXAcc XAccessible interface.
+ * @return Com accobject interface.
+ */
+IMAccessible* AccObjectWinManager::GetIMAccByXAcc(XAccessible* pXAcc)
+{
+ AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
+ if(pAccObj)
+ {
+ return pAccObj->GetIMAccessible();
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/**
+ * Query and get IAccessible interface by child id from list.
+ * @param resID, childID.
+ * @return Com accobject interface.
+ */
+IMAccessible * AccObjectWinManager::GetIAccessibleFromResID(long resID)
+{
+ XResIdToAccObjHash::iterator pIndTemp = XResIdAccList.find( resID );
+ if ( pIndTemp == XResIdAccList.end() )
+ return NULL;
+
+ AccObject* pObj = pIndTemp->second;
+
+ if(pObj->GetIMAccessible())
+ return pObj->GetIMAccessible();
+ return NULL;
+}
+/**
+ * Notify some object will be destroyed.
+ * @param pXAcc XAccessible interface.
+ * @return Com accobject interface.
+ */
+void AccObjectWinManager::NotifyDestroy(XAccessible* pXAcc)
+{
+ AccObject* accObj = GetAccObjByXAcc(pXAcc);
+ if(accObj)
+ {
+ accObj->NotifyDestroy(sal_True);
+ }
+}
+
+
+void AccObjectWinManager::UpdateChildState(com::sun::star::accessibility::XAccessible* pAccSubMenu)
+{
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY);
+ if (!xContext.is())
+ {
+ return;
+ }
+ sal_Int32 nCount = xContext->getAccessibleChildCount();
+ for (sal_Int32 i = 0 ; i < nCount ; ++i)
+ {
+ Reference<com::sun::star::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i);
+ if (xChild.is())
+ {
+ AccObject *pObj = GetAccObjByXAcc(xChild.get());
+ if (pObj)
+ {
+ pObj->UpdateState();
+ }
+ }
+ }
+}
+
+
+bool AccObjectWinManager::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ if (pXAcc && oldFocus != pXAcc)
+ {
+ if(GetParentRole(pXAcc) == TOOL_BAR)
+ {
+ Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext());
+ if (pRContext.is())
+ {
+ if(pRContext->getAccessibleRole() == TOGGLE_BUTTON)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+short AccObjectWinManager::GetRole(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ assert(pXAcc != NULL);
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
+ if(xContext.is())
+ {
+ return xContext->getAccessibleRole();
+ }
+ return -1;
+}
+
+XAccessible* AccObjectWinManager::GetAccDocByHWND( long pWnd )
+{
+ XHWNDToDocumentHash::iterator aIter;
+ aIter = XHWNDDocList.find( pWnd );
+ if ( aIter != XHWNDDocList.end() )
+ {
+ return aIter->second;
+ }
+
+ return NULL;
+}
+
+XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ long pWnd = (long)( pAccObj->GetParentHWND() );
+ return GetAccDocByHWND( pWnd );
+}
+
+bool AccObjectWinManager::IsTopWinAcc( com::sun::star::accessibility::XAccessible* pXAcc )
+{
+ bool bRet = false;
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if ( pAccObj )
+ {
+ bRet = ( pAccObj->GetParentObj() == NULL );
+ }
+ return bRet;
+} \ No newline at end of file