1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include <cassert>
23 
24 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
25 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
26 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 
29 #include <oleacc.h>
30 #ifndef _SV_AccObjectWinManager_HXX
31 #include "AccObjectWinManager.hxx"
32 #endif
33 #include "AccEventListener.hxx"
34 #include "AccComponentEventListener.hxx"
35 #include "AccContainerEventListener.hxx"
36 #include "AccDialogEventListener.hxx"
37 #include "AccWindowEventListener.hxx"
38 #include "AccFrameEventListener.hxx"
39 #include "AccMenuEventListener.hxx"
40 #include "AccObjectContainerEventListener.hxx"
41 #include "AccParagraphEventListener.hxx"
42 #include "AccTextComponentEventListener.hxx"
43 #include "AccListEventListener.hxx"
44 #include "AccTreeEventListener.hxx"
45 #include "AccTableEventListener.hxx"
46 #include "AccObject.hxx"
47 #include "AccessibleEventId.h"
48 #include "AccessibleApplication.h"
49 #include "AccessibleApplication_i.c"
50 #include "unomsaaevent.hxx"
51 #include "checkmt.hxx"
52 
53 #define CHILDID_SELF             0
54 
55 
56 using namespace std;
57 using namespace com::sun::star::accessibility;
58 using namespace com::sun::star::uno;
59 
60 AccObjectWinManager* g_acc_manager = NULL;
61 AccObjectWinManager* AccObjectWinManager::me = NULL;
62 
63 /**
64    * Implementation of interface XMSAAService's method getAccObjectPtr() that return the
65    * corresponding com interface with the MS event.
66    *
67    * @param
68    * @return  Com interface.
69    */
70 long GetMSComPtr(long hWnd, long lParam, long wParam)
71 {
72     if( g_acc_manager )
73         return (long)g_acc_manager->Get_ToATInterface(HWND((void*)hWnd),lParam,wParam );
74     return NULL;
75 }
76 
77 /**
78    * constructor
79    * @param   Agent The agent kept in all listeners,it's the sole interface by which
80    *                listener communicate with windows manager.
81    *          pEventAccObj The present event accobject.
82    *          oldFocus     Last focused object.
83    *          isSelectionChanged flag that identifies if there is selection changed.
84    *		  selectionChildObj  Selected object.
85    *          dChildID	Chile resource ID.
86    *          hAcc TopWindowHWND
87    * @return
88    */
89 AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ):
90         pAgent( Agent ),
91         oldFocus( NULL )
92 {
93 	m_bBridgeRegistered =IsBridgeRegisteredAcc();
94 }
95 
96 /**
97    * Public method to produce manager
98    * @param   Agent The agent kept in all listeners,it's the sole interface by which
99    *          listener communicate with windows manager.
100    * @return
101    */
102 AccObjectWinManager* AccObjectWinManager::CreateAccObjectWinManagerInstance( AccObjectManagerAgent* Agent )
103 {
104     if( me == NULL )
105     {
106         me = new AccObjectWinManager( Agent );
107         g_acc_manager = me;
108         return me;
109     }
110 
111     return me;
112 }
113 
114 
115 /**
116    * Destructor,clear all resource.
117    * @param
118    * @return
119    */
120 AccObjectWinManager::~AccObjectWinManager()
121 {
122     XIdAccList.clear();
123     HwndXAcc.clear();
124     XResIdAccList.clear();
125     XHWNDDocList.clear();
126 #ifdef ACC_DEBUG
127 
128     fclose( pFile );
129 #endif
130 }
131 
132 
133 /**
134    * Get valid com object interface when notifying some MSAA event
135    * @param pWND The top window handle that contains that event control.
136    * @param wParam Windows system interface.
137    * @return Com interface with event.
138    */
139 
140 long AccObjectWinManager::Get_ToATInterface( HWND hWnd, long lParam, long wParam)
141 {
142     vos::OGuard localGuard(maATInterfaceMutex);//
143 
144     IMAccessible* pRetIMAcc = NULL;
145 
146     if(lParam == OBJID_CLIENT )
147     {
148         AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd);
149         if(topWindowAccObj)
150         {
151             pRetIMAcc = topWindowAccObj->GetIMAccessible();
152             if(pRetIMAcc)
153                 pRetIMAcc->AddRef();//increase COM reference count
154         }
155     }
156 
157     if ( pRetIMAcc && lParam == OBJID_CLIENT )
158     {
159         IAccessible* pTemp = dynamic_cast<IAccessible*>( pRetIMAcc );
160         HRESULT result = LresultFromObject(IID_IAccessible, wParam, pTemp);
161         pTemp->Release();
162         return result;
163     }
164     return 0;
165 }
166 
167 /**
168    * Search AccObject by XAccessible pointer from our container.
169    * @param pXAcc XAccessible interface.
170    * @return Pointer of accObject that is found.
171    */
172 AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc)
173 {
174     if( pXAcc == NULL)
175         return NULL;
176 
177     XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
178     if ( pIndTemp == XIdAccList.end() )
179         return NULL;
180 
181     return &(pIndTemp->second);
182 }
183 
184 /**
185    * Search XAccessible by AccObject pointer from our container.
186    * @param pAccObj AccObject pointer.
187    * @return Pointer of XAccessible Interface.
188    */
189 XAccessible* AccObjectWinManager::GetXAccByAccObj(AccObject* pAccObj)
190 {
191     XIdToAccObjHash::iterator iter = XIdAccList.begin();
192     while(iter!=XIdAccList.end())
193     {
194         AccObject* tmp = &(iter->second);
195         if(tmp== pAccObj)
196             return (XAccessible*)(iter->first);
197         iter++;
198     }
199     return NULL;
200 }
201 
202 /**
203    * get acc object of top window by its handle
204    * @param hWnd, top window handle
205    * @return pointer to AccObject
206    */
207 AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd)
208 {
209     XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
210     if(iterResult == HwndXAcc.end())
211         return NULL;
212     XAccessible* pXAcc = (XAccessible*)(iterResult->second);
213     return GetAccObjByXAcc(pXAcc);
214 }
215 
216 /**
217    * Simulate MSAA event via XAccessible interface and event type.
218    * @param pXAcc XAccessible interface.
219    * @param state Customize Interface
220    * @return The terminate result that identifies if the call is successful.
221    */
222 sal_Bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc,short state)
223 {
224     vos::OGuard aGuard(aNotifyMutex);
225 
226 	if (!m_bBridgeRegistered)
227 	{
228 		return sal_False;
229 	}
230     if (!IsInMainThread())
231     {
232         return sal_False;
233     }
234 
235     Reference< XAccessibleContext > pRContext;
236 
237     if( pXAcc == NULL)
238         return sal_False;
239 
240 
241     pRContext = pXAcc->getAccessibleContext();
242     if( !pRContext.is() )
243         return sal_False;
244 
245 
246     AccObject* selfAccObj= GetAccObjByXAcc(pXAcc);
247 
248     if(selfAccObj==NULL)
249         return sal_False;
250 
251     int selectNum =0;
252 
253     long dChildID = selfAccObj->GetResID();
254     HWND hAcc = selfAccObj->GetParentHWND();
255 
256     switch(state)
257     {
258     case UM_EVENT_STATE_FOCUSED:
259         {
260             UpdateAccFocus(pXAcc);
261             if( selfAccObj )
262                 selfAccObj->UpdateDefaultAction( );
263             UpdateValue(pXAcc);
264             NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID  );
265             break;
266         }
267     case UM_EVENT_STATE_BUSY:
268         NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
269         break;
270     case UM_EVENT_STATE_CHECKED:
271         NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
272         break;
273     case UM_EVENT_STATE_PRESSED:
274         NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
275         break;
276 
277     //Removed fire out selected event
278     //case UM_EVENT_STATE_SELECTED:
279     //	NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID  );
280     //	break;
281     case UM_EVENT_STATE_ARMED:
282         UpdateAccFocus(pXAcc);
283         NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID  );
284         break;
285     case UM_EVENT_MENU_START:
286         NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID  );
287         break;
288     case UM_EVENT_MENU_END:
289         NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID  );
290         break;
291     case UM_EVENT_MENUPOPUPSTART:
292         NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID  );
293         break;
294     case UM_EVENT_MENUPOPUPEND:
295         NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID  );
296         break;
297     case UM_EVENT_SELECTION_CHANGED:
298         NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID  );
299         break;
300     case UM_EVENT_SELECTION_CHANGED_ADD:
301        	NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID  );
302        	break;
303     case UM_EVENT_SELECTION_CHANGED_REMOVE:
304        	NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID  );
305        	break;
306     case UM_EVENT_SELECTION_CHANGED_WITHIN:
307        	NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID  );
308        	break;
309     case UM_EVENT_OBJECT_VALUECHANGE:
310         UpdateValue(pXAcc);
311         NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID  );
312         break;
313     case UM_EVENT_OBJECT_NAMECHANGE:
314         NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID  );
315         break;
316     case UM_EVENT_OBJECT_DESCRIPTIONCHANGE:
317         NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID  );
318         break;
319     case UM_EVENT_OBJECT_DEFACTIONCHANGE:
320         NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
321         break;
322     case UM_EVENT_OBJECT_CARETCHANGE:
323         NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID  );
324         break;
325     case UM_EVENT_OBJECT_TEXTCHANGE:
326         NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
327         break;
328     case UM_EVENT_ACTIVE_DESCENDANT_CHANGED:
329         UpdateAccFocus(pXAcc);
330         NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID  );
331         break;
332     case UM_EVENT_BOUNDRECT_CHANGED:
333         NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID  );
334         break;
335     case UM_EVENT_VISIBLE_DATA_CHANGED:
336         NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
337         break;
338     case UM_EVENT_SHOW :
339         NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID  );
340         NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID  );
341 	break;
342     case UM_EVENT_TABLE_CAPTION_CHANGED:
343         NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
344         break;
345     case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
346         NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
347         break;
348     case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED:
349         NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
350         break;
351     case UM_EVENT_TABLE_MODEL_CHANGED:
352         NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
353         break;
354     case UM_EVENT_TABLE_ROW_HEADER_CHANGED:
355         NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
356         break;
357     case UM_EVENT_TABLE_SUMMARY_CHANGED:
358         NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
359         break;
360     case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
361         NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
362         break;
363     case UM_EVENT_OBJECT_REORDER:
364         NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID  );
365         break;
366     case UM_EVENT_PAGE_CHANGED:
367         NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID  );
368         break;
369     case UM_EVENT_CHILD_REMOVED:
370         NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID  );
371         break;
372     case UM_EVENT_CHILD_ADDED:
373         NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID  );
374         break;
375     case UM_EVENT_OBJECT_PAGECHANGED:
376         NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
377         break;
378     case UM_EVENT_TEXT_SELECTION_CHANGED:
379         NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
380         break;
381     case UM_EVENT_SECTION_CHANGED:
382         NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
383         break;
384     case UM_EVENT_COLUMN_CHANGED:
385         NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID  );
386         break;
387     default:
388         break;
389     }
390 
391     return sal_True;
392 }
393 
394 /**
395    * Get Parent XAccessible interface by XAccessible interface.
396    * @param pXAcc XAccessible interface.
397    * @return Parent XAccessible interface.
398    */
399 XAccessible* AccObjectWinManager::GetParentXAccessible( XAccessible* pXAcc )
400 {
401     AccObject* pObj= GetAccObjByXAcc(pXAcc);
402     if( pObj ==NULL )
403         return NULL;
404     if(pObj->GetParentObj())
405     {
406         pObj = pObj->GetParentObj();
407         return pObj->GetXAccessible().get();
408     }
409     return NULL;
410 }
411 
412 /**
413    * Get Parent role by XAccessible interface.
414    * @param pXAcc XAccessible interface.
415    * @return Parent role.
416    */
417 short AccObjectWinManager::GetParentRole( XAccessible* pXAcc )
418 {
419     AccObject* pObj= GetAccObjByXAcc(pXAcc);
420     if( pObj ==NULL )
421         return -1;
422     if(pObj->GetParentObj())
423     {
424         pObj = pObj->GetParentObj();
425         if(pObj->GetXAccessible().is())
426         {
427             XAccessible* pXAcc = pObj->GetXAccessible().get();
428             Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
429             if(pRContext.is())
430                 return pRContext->getAccessibleRole();
431         }
432     }
433     return -1;
434 }
435 
436 /**
437    * Update focus objcet by new focused XAccessible interface.
438    * @param newFocus New XAccessible interface that gets focus.
439    * @return
440    */
441 void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus)
442 {
443     AccObject* pAccObjNew = GetAccObjByXAcc(newFocus);
444     if(pAccObjNew)
445     {
446         AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus);
447         oldFocus = newFocus;
448         pAccObjNew->setFocus();
449         //if old == new, the pAccObjNew will be without focused state
450         if (pAccObjOld && pAccObjOld != pAccObjNew)
451             pAccObjOld->unsetFocus();
452     }
453 }
454 
455 /**
456    * Update selected objcet by new focused XAccessible interface.
457    * @param pXAcc XAccessible interface that has selected child changed.
458    * @return Selected children count.
459    */
460 int AccObjectWinManager::UpdateAccSelection(XAccessible* pXAcc)
461 {
462     XAccessibleSelection* pSelection = NULL;
463     Reference< XAccessibleContext > pRContext;
464 
465     if( pXAcc == NULL)
466         return sal_False;
467 
468     pRContext = pXAcc->getAccessibleContext();
469     if( !pRContext.is() )
470         return sal_False;
471 
472     Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
473     if( !pRSelection.is() )
474         return sal_False;
475 
476     AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
477     if(pAccObj==NULL)
478         return sal_False;
479 
480     Reference<XAccessible> pRChild = NULL;
481     AccObject* pAccChildObj = NULL;
482     int selectNum= pRSelection->getSelectedAccessibleChildCount();
483 
484     IAccSelectionList oldSelection = pAccObj->GetSelection();
485 
486     if(selectNum > 4)//for selected.
487         return selectNum;
488     if(selectNum == 1 && oldSelection.size() == 0)
489         return 1;
490 
491     for (int i=0;i<selectNum;i++)
492     {
493         pRChild = pRSelection->getSelectedAccessibleChild(i);
494         if(!pRChild.is())
495         {
496             continue;
497         }
498         Reference<XAccessibleContext> pRChildContext = pRChild->getAccessibleContext();
499         if(!pRChildContext.is())
500         {
501             continue;
502         }
503         long index = pRChildContext->getAccessibleIndexInParent();
504         IAccSelectionList::iterator temp = oldSelection.find(index);
505         if ( temp != oldSelection.end() )
506         {
507             oldSelection.erase(index);
508             continue;
509         }
510 
511         pAccChildObj = NULL;
512         pAccChildObj = GetAccObjByXAcc(pRChild.get());
513         if(!pAccChildObj)
514         {
515             InsertAccObj(pRChild.get(), pXAcc,pAccObj->GetParentHWND());
516             pAccChildObj = GetAccObjByXAcc(pRChild.get());
517         }
518 
519         pAccObj->AddSelect(index, pAccChildObj);
520 
521         if(pAccChildObj != NULL)
522             NotifyWinEvent(EVENT_OBJECT_SELECTIONADD,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
523     }
524 
525     IAccSelectionList::iterator iter = oldSelection.begin();
526     while(iter!=oldSelection.end())
527     {
528         pAccObj->GetSelection().erase(iter->first);
529         pAccChildObj = (AccObject*)(iter->second);
530         if(pAccChildObj != NULL)
531             NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
532         iter++;
533     }
534     return 0;
535 
536 }
537 
538 /**
539    * Delete child element from children list.
540    * @param pObj Child element that should be removed from parant child list.
541    * @return
542    */
543 void AccObjectWinManager::DeleteAccChildNode( AccObject* pObj )
544 {
545     AccObject *parentAccObj = pObj->GetParentObj();
546     if( parentAccObj )
547         parentAccObj->DeleteChild( pObj );
548 }
549 
550 /**
551    * Delete XAccessible items in top window handle hashtable
552    * @param pXAcc XAccessible interface.
553    * @return
554    */
555 void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible* pXAcc )
556 {
557     XHWNDToXAccHash::iterator iter = HwndXAcc.begin();
558     while(iter!=HwndXAcc.end())
559     {
560         if(iter->second == pXAcc )
561         {
562             HwndXAcc.erase(iter);
563             return;
564         }
565         iter++;
566     }
567 }
568 
569 /**
570    * Delete Delete all children with the tree root of XAccessible pointer
571    * @param pXAcc Tree root XAccessible interface.
572    * @return
573    */
574 void AccObjectWinManager::DeleteChildrenAccObj(XAccessible* pXAcc)
575 {
576     vos::OGuard aGuard( aDeleteMutex );
577     AccObject* currentObj=NULL;
578     AccObject* childObj=NULL;
579     XAccessible* pTmpXAcc=NULL;
580 
581     currentObj =  GetAccObjByXAcc( pXAcc);
582     if(currentObj)
583     {
584         childObj = currentObj->NextChild();
585         while(childObj)
586         {
587             pTmpXAcc = GetXAccByAccObj(childObj);
588             if(pTmpXAcc)
589             {
590                 DeleteChildrenAccObj(pTmpXAcc);
591                 DeleteAccObj(pTmpXAcc);
592             }
593             childObj = currentObj->NextChild();
594         }
595     }
596 }
597 
598 /**
599    * Delete Delete Acc object self.
600    * @param pXAcc The XAccessible interface.
601    * @return
602    */
603 void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
604 {
605     vos::OGuard aGuard( aDeleteMutex );
606     if( pXAcc == NULL )
607         return;
608     XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
609     if( temp != XIdAccList.end() )
610     {
611         ResIdGen.SetSub( temp->second.GetResID() );
612     }
613     else
614     {
615         return;
616     }
617 
618     AccObject& accObj = temp->second;
619     DeleteAccChildNode( &accObj );
620     DeleteAccListener( &accObj );
621     if( accObj.GetIMAccessible() )
622     {
623         accObj.GetIMAccessible()->Release();
624     }
625     XIdAccList.erase( pXAcc );
626     XResIdAccList.erase( accObj.GetResID() );
627     DeleteFromHwndXAcc(pXAcc);
628 }
629 
630 /**
631    * Delete listener that inspects some XAccessible object
632    * @param pAccObj Accobject pointer.
633    * @return
634    */
635 void AccObjectWinManager::DeleteAccListener( AccObject*  pAccObj )
636 {
637     AccEventListener* listener = pAccObj->getListener();
638     if( listener==NULL )
639         return;
640     listener->removeMeFromBroadcaster();
641     pAccObj->SetListener(NULL);
642 }
643 
644 /**
645    * Generate a child ID, which is used for AT
646    * @param
647    * @return New resource ID.
648    */
649 inline long AccObjectWinManager::ImpleGenerateResID()
650 {
651     return ResIdGen.GenerateNewResID();
652 }
653 
654 /**
655    * Insert all children of the current acc object
656    * @param pXAcc XAccessible interface
657    * @param pWnd  Top Window handle
658    * @return The calling result.
659    */
660 sal_Bool AccObjectWinManager::InsertChildrenAccObj( com::sun::star::accessibility::XAccessible* pXAcc,
661         HWND pWnd)
662 {
663     if(!IsContainer(pXAcc))
664         return sal_False;
665 
666     Reference< XAccessibleContext > pRContext;
667 
668     if( pXAcc == NULL)
669         return sal_False;
670     pRContext = pXAcc->getAccessibleContext();
671     if( !pRContext.is() )
672         return sal_False;
673 
674     short role = pRContext->getAccessibleRole();
675 
676     if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role )
677     {
678         if(IsStateManageDescendant(pXAcc))
679         {
680             return sal_True;
681         }
682     }
683 
684     int count = pRContext->getAccessibleChildCount();
685     for (int i=0;i<count;i++)
686     {
687         Reference<XAccessible> mxAccessible
688         = pRContext->getAccessibleChild(i);
689         XAccessible* mpAccessible = mxAccessible.get();
690         if(mpAccessible != NULL)
691         {
692             InsertAccObj( mpAccessible,pXAcc,pWnd );
693             InsertChildrenAccObj(mpAccessible,pWnd);
694         }
695     }
696 
697     return sal_True;
698 }
699 
700 /**
701    * Insert child object.
702    * @param pCurObj The child object
703    * @param pParentObj The parant object
704    * @param pWnd Top window handle.
705    * @return
706    */
707 void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pParentObj, HWND /* pWnd */ )
708 {
709     if(pCurObj)
710     {
711         if(pParentObj)
712         {
713             pParentObj->InsertChild(pCurObj);
714         }
715         else
716         {
717             pCurObj->UpdateValidWindow();
718         }
719     }
720 }
721 
722 /**
723    * Insert child object.
724    * @param pCurObj The child object
725    * @param pParentObj The parant object
726    * @param pWnd Top window handle.
727    * @return
728    */
729 sal_Bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd )
730 {
731 	if (!m_bBridgeRegistered)
732 	{
733 		return sal_False;
734 	}
735     XIdToAccObjHash::iterator itXacc = XIdAccList.find( (void*)pXAcc );
736     if (itXacc != XIdAccList.end() )
737     {
738         short nCurRole =GetRole(pXAcc);
739         if (AccessibleRole::SHAPE == nCurRole)
740         {
741             AccObject &objXacc = itXacc->second;
742             AccObject *pObjParent = objXacc.GetParentObj();
743             if (pObjParent &&
744                     pObjParent->GetXAccessible().is() &&
745                     pObjParent->GetXAccessible().get() != pParentXAcc)
746             {
747                 XIdToAccObjHash::iterator itXaccParent  = XIdAccList.find( (void*)pParentXAcc );
748                 if(itXaccParent != XIdAccList.end())
749                 {
750                     objXacc.SetParentObj(&(itXaccParent->second));
751                 }
752             }
753         }
754         return sal_False;
755     }
756 
757 
758     Reference< XAccessibleContext > pRContext;
759 
760     if( pXAcc == NULL)
761         return sal_False;
762 
763     pRContext = pXAcc->getAccessibleContext();
764     if( !pRContext.is() )
765         return sal_False;
766 
767     if( pWnd == NULL )
768     {
769         if(pParentXAcc)
770         {
771             AccObject* pObj = GetAccObjByXAcc(pParentXAcc);
772             if(pObj)
773                 pWnd = pObj->GetParentHWND();
774         }
775         if( pWnd == NULL )
776             return sal_False;
777     }
778 
779     AccObject pObj( pXAcc,pAgent );
780     if( pObj.GetIMAccessible() == NULL )
781         return sal_False;
782     pObj.SetResID( this->ImpleGenerateResID());
783     pObj.SetParentHWND( pWnd );
784 
785     //for file name support
786     if ( pObj.GetRole() == DOCUMENT )
787     {
788         XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find( (long)pWnd );
789         if ( aIter != XHWNDDocList.end() )
790         {
791             XHWNDDocList.erase( aIter );
792         }
793         XHWNDDocList.insert( XHWNDToDocumentHash::value_type( (long)pWnd, pXAcc ) );
794 
795     }
796     //end of file name
797 
798     AccEventListener* listener = createAccEventListener(pXAcc, pAgent);
799     if(listener==NULL)
800         return sal_False;
801     Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
802     Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
803     if (broadcaster.is())
804     {
805         Reference <XAccessibleEventListener> pp (
806             static_cast< XAccessibleEventListener* >(listener),UNO_QUERY );
807         if(pp.is())
808         {
809             broadcaster->addEventListener(pp);
810         }
811         else
812         {
813             delete listener;
814             return sal_False;
815         }
816     }
817     else
818         return sal_False;
819 
820     XIdAccList.insert( XIdToAccObjHash::value_type( (void*)pXAcc, pObj ));
821     XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
822     XResIdAccList.insert(XResIdToAccObjHash::value_type(pObj.GetResID(),&(pIndTemp->second)));
823 
824     AccObject* pCurObj = GetAccObjByXAcc(pXAcc);
825     if( pCurObj )
826     {
827         pCurObj->SetListener( listener );
828         if(listener != NULL)
829             listener->acquire();
830     }
831 
832     AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc);
833     InsertAccChildNode(pCurObj,pParentObj,pWnd);
834     if( pCurObj )
835         pCurObj->UpdateAccessibleInfoFromUnoToMSAA();
836     return sal_True;
837 }
838 
839 
840 /**
841    * save the pair <topwindowhandle, XAccessible>
842    * @param hWnd, top window handle
843    * @param pXAcc XAccessible interface for top window
844    * @return void
845    */
846 void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, com::sun::star::accessibility::XAccessible* pXAcc)
847 {
848     HwndXAcc.insert( XHWNDToXAccHash::value_type( hWnd,(void*)pXAcc ) );
849 }
850 
851 
852 /**
853    * create the corresponding listener.
854    * @param pXAcc XAccessible interface.
855    * @param Agent The agent kept in all listeners,it's the sole interface by which
856    *        listener communicate with windows manager.
857    * @return
858    */
859 AccEventListener* AccObjectWinManager::createAccEventListener(XAccessible* pXAcc, AccObjectManagerAgent* /* Agent */ )
860 {
861     AccEventListener* listener = NULL;
862     Reference<XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
863     if(xContext.is())
864     {
865         switch( xContext->getAccessibleRole() )
866         {
867         case /*AccessibleRole::*/DIALOG:
868             listener = new AccDialogEventListener(pXAcc,pAgent);
869             break;
870         case /*AccessibleRole::*/FRAME:
871             listener = new AccFrameEventListener(pXAcc,pAgent);
872             break;
873         case /*AccessibleRole::*/WINDOW:
874             listener = new AccWindowEventListener(pXAcc,pAgent);
875             break;
876         case /*AccessibleRole::*/ROOT_PANE:
877             listener = new AccFrameEventListener(pXAcc,pAgent);
878             break;
879             //Container
880         case /*AccessibleRole::*/CANVAS:
881         case /*AccessibleRole::*/COMBO_BOX:
882         case /*AccessibleRole::*/DOCUMENT:
883         case /*AccessibleRole::*/END_NOTE:
884         case /*AccessibleRole::*/FILLER:
885         case /*AccessibleRole::*/FOOTNOTE:
886         case /*AccessibleRole::*/FOOTER:
887         case /*AccessibleRole::*/HEADER:
888         case /*AccessibleRole::*/LAYERED_PANE:
889         case /*AccessibleRole::*/MENU_BAR:
890         case /*AccessibleRole::*/POPUP_MENU:
891         case /*AccessibleRole::*/OPTION_PANE:
892         case /*AccessibleRole::*/PAGE_TAB:
893         case /*AccessibleRole::*/PAGE_TAB_LIST:
894         case /*AccessibleRole::*/PANEL:
895         case /*AccessibleRole::*/SCROLL_PANE:
896         case /*AccessibleRole::*/SPLIT_PANE:
897         case /*AccessibleRole::*/STATUS_BAR:
898         case /*AccessibleRole::*/TABLE_CELL:
899         case /*AccessibleRole::*/TOOL_BAR:
900         case /*AccessibleRole::*/VIEW_PORT:
901             listener = new AccContainerEventListener(pXAcc,pAgent);
902             break;
903         case /*AccessibleRole::*/PARAGRAPH:
904         case /*AccessibleRole::*/HEADING:
905             listener = new AccParagraphEventListener(pXAcc,pAgent);
906             break;
907             //Component
908         case /*AccessibleRole::*/CHECK_BOX:
909         case /*AccessibleRole::*/ICON:
910         case /*AccessibleRole::*/LABEL:
911         case /*AccessibleRole::*/MENU_ITEM:
912         case /*AccessibleRole::*/CHECK_MENU_ITEM:
913         case /*AccessibleRole::*/RADIO_MENU_ITEM:
914         case /*AccessibleRole::*/PUSH_BUTTON:
915         case /*AccessibleRole::*/RADIO_BUTTON:
916         case /*AccessibleRole::*/SCROLL_BAR:
917         case /*AccessibleRole::*/SEPARATOR:
918         case /*AccessibleRole::*/TOGGLE_BUTTON:
919         case /*AccessibleRole::*/BUTTON_DROPDOWN:
920         case /*AccessibleRole::*/TOOL_TIP:
921         case /*AccessibleRole::*/SPIN_BOX:
922         case DATE_EDITOR:
923             listener = new AccComponentEventListener(pXAcc,pAgent);
924             break;
925             //text component
926         case /*AccessibleRole::*/TEXT:
927             listener = new AccTextComponentEventListener(pXAcc,pAgent);
928             break;
929             //menu
930         case /*AccessibleRole::*/MENU:
931             listener = new AccMenuEventListener(pXAcc,pAgent);
932             break;
933             //object container
934         case /*AccessibleRole::*/SHAPE:
935 
936         case /*AccessibleRole::*/EMBEDDED_OBJECT:
937         case /*AccessibleRole::*/GRAPHIC:
938         case /*AccessibleRole::*/TEXT_FRAME:
939             listener = new AccObjectContainerEventListener(pXAcc,pAgent);
940             break;
941             //descendmanager
942         case /*AccessibleRole::*/LIST:
943             listener = new AccListEventListener(pXAcc,pAgent);
944             break;
945         case /*AccessibleRole::*/TREE:
946             listener = new AccTreeEventListener(pXAcc,pAgent);
947             break;
948             //special
949         case /*AccessibleRole::*/COLUMN_HEADER:
950         case /*AccessibleRole::*/TABLE:
951             listener = new AccTableEventListener(pXAcc,pAgent);
952             break;
953         default:
954             listener = new AccContainerEventListener(pXAcc,pAgent);
955             break;
956         }
957     }
958 
959     return listener;
960 }
961 
962 /**
963    * state is a combination integer, each bit of which represents a single state,
964    * such as focused,1 for the state on,0 for the state off. Here call COM interface
965    * to modify the state value, including DecreaseState.
966    * @param pXAcc XAccessible interface.
967    * @param pState Changed state.
968    * @return
969    */
970 void AccObjectWinManager::DecreaseState( XAccessible* pXAcc,unsigned short pState )
971 {
972     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
973     if( pAccObj )
974         pAccObj->DecreaseState( pState );
975 }
976 
977 /**
978    * state is a combination integer, each bit of which represents a single state,such as focused,1 for
979    * the state on,0 for the state off. Here call COM interface to modify the state value, including
980    * IncreaseState.
981    * @param pXAcc XAccessible interface.
982    * @param pState Changed state.
983    * @return
984    */
985 void AccObjectWinManager::IncreaseState( XAccessible* pXAcc,unsigned short pState )
986 {
987     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
988     if( pAccObj )
989         pAccObj->IncreaseState( pState );
990 }
991 
992 void  AccObjectWinManager::UpdateState( com::sun::star::accessibility::XAccessible* pXAcc )
993 {
994     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
995     if( pAccObj )
996         pAccObj->UpdateState( );
997 }
998 
999 /**
1000    * Set corresponding com object's accessible name via XAccessilbe interface and new
1001    * name
1002    * @param pXAcc XAccessible interface.
1003    * @return
1004    */
1005 void  AccObjectWinManager::UpdateAccName( XAccessible* pXAcc )
1006 {
1007     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1008     if( pAccObj )
1009         pAccObj->UpdateName();
1010 }
1011 
1012 void  AccObjectWinManager::UpdateAction( XAccessible* pXAcc )
1013 {
1014     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1015     if( pAccObj )
1016         pAccObj->UpdateAction();
1017 }
1018 
1019 void AccObjectWinManager::UpdateDescription( XAccessible* pXAcc )
1020 {
1021     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1022     if ( pAccObj )
1023         pAccObj->UpdateDescription();
1024 }
1025 
1026 /**
1027    * Set corresponding com object's accessible location via XAccessilbe interface and new
1028    * location.
1029    * @param pXAcc XAccessible interface.
1030    * @return
1031    */
1032 void  AccObjectWinManager::SetLocation( XAccessible* pXAcc, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
1033 {
1034     AccObject* pObj = GetAccObjByXAcc( pXAcc );
1035     //get the location from XComponent.
1036     Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
1037     if( pObj )
1038         pObj->UpdateLocation();
1039 }
1040 
1041 /**
1042    * Set corresponding com object's value  via XAccessilbe interface and new value.
1043    * @param pXAcc XAccessible interface.
1044    * @param pAny new value.
1045    * @return
1046    */
1047 void  AccObjectWinManager::SetValue( XAccessible* pXAcc, Any pAny )
1048 {
1049     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1050     if( pAccObj )
1051         pAccObj->SetValue( pAny );
1052 }
1053 
1054 /**
1055    * Set corresponding com object's value  via XAccessilbe interface.
1056    * @param pXAcc XAccessible interface.
1057    * @return
1058    */
1059 void  AccObjectWinManager::UpdateValue( XAccessible* pXAcc )
1060 {
1061     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1062     if( pAccObj )
1063         pAccObj->UpdateValue();
1064 }
1065 
1066 /**
1067    * Set corresponding com object's name via XAccessilbe interface and new name.
1068    * @param pXAcc XAccessible interface.
1069    * @param newName new name
1070    * @return
1071    */
1072 void  AccObjectWinManager::SetAccName( XAccessible* pXAcc, Any newName)
1073 {
1074     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1075     if( pAccObj )
1076         pAccObj->SetName( newName );
1077 }
1078 
1079 /**
1080    * Set corresponding com object's description via XAccessilbe interface and new description.
1081    * @param pXAcc XAccessible interface.
1082    * @param newDesc new description
1083    * @return
1084    */
1085 void  AccObjectWinManager::SetDescription( XAccessible* pXAcc, Any newDesc )
1086 {
1087     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1088     if( pAccObj )
1089         pAccObj->SetDescription( newDesc );
1090 }
1091 
1092 /**
1093    * Set corresponding com object's role via XAccessilbe interface and new role.
1094    * @param pXAcc XAccessible interface.
1095    * @param Role new role
1096    * @return
1097    */
1098 void  AccObjectWinManager::SetRole( XAccessible* pXAcc, long Role )
1099 {
1100     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1101     if( pAccObj )
1102         pAccObj->SetRole( (short)Role );
1103 }
1104 
1105 /**
1106    * Judge if a XAccessible object is a container object.
1107    * @param pAccessible XAccessible interface.
1108    * @return If XAccessible object is container.
1109    */
1110 sal_Bool AccObjectWinManager::IsContainer(XAccessible* pAccessible)
1111 {
1112     try
1113     {
1114         if(pAccessible)
1115         {
1116             Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
1117             if(xContext.is())
1118             {
1119                 switch( xContext->getAccessibleRole() )
1120                 {
1121                 case /*AccessibleRole::*/DIALOG:
1122                 case /*AccessibleRole::*/FRAME:
1123                 case /*AccessibleRole::*/WINDOW:
1124                 case /*AccessibleRole::*/ROOT_PANE:
1125                 case /*AccessibleRole::*/CANVAS:
1126                 case /*AccessibleRole::*/COMBO_BOX:
1127                 case /*AccessibleRole::*/DOCUMENT:
1128                 case /*AccessibleRole::*/EMBEDDED_OBJECT:
1129                 case /*AccessibleRole::*/END_NOTE:
1130                 case /*AccessibleRole::*/FILLER:
1131                 case /*AccessibleRole::*/FOOTNOTE:
1132                 case /*AccessibleRole::*/FOOTER:
1133                 case /*AccessibleRole::*/GRAPHIC:
1134                 case /*AccessibleRole::*/GROUP_BOX:
1135                 case /*AccessibleRole::*/HEADER:
1136                 case /*AccessibleRole::*/LAYERED_PANE:
1137                 case /*AccessibleRole::*/MENU_BAR:
1138                 case /*AccessibleRole::*/POPUP_MENU:
1139                 case /*AccessibleRole::*/OPTION_PANE:
1140                 case /*AccessibleRole::*/PAGE_TAB:
1141                 case /*AccessibleRole::*/PAGE_TAB_LIST:
1142                 case /*AccessibleRole::*/PANEL:
1143                 case /*AccessibleRole::*/SCROLL_PANE:
1144                 case /*AccessibleRole::*/SPLIT_PANE:
1145                 case /*AccessibleRole::*/STATUS_BAR:
1146                 case /*AccessibleRole::*/TABLE_CELL:
1147                 case /*AccessibleRole::*/TEXT_FRAME:
1148                 case /*AccessibleRole::*/TOOL_BAR:
1149                 case /*AccessibleRole::*/VIEW_PORT:
1150                 case /*AccessibleRole::*/SHAPE:
1151                     return sal_True;
1152                     break;
1153                 case /*AccessibleRole::*/COLUMN_HEADER:
1154                 case /*AccessibleRole::*/TABLE:
1155                     if(!IsStateManageDescendant(pAccessible))
1156                         return sal_True;
1157                     break;
1158                 case /*AccessibleRole::*/MENU:
1159                     return sal_True;
1160                     break;
1161                 default:
1162                     return sal_False;
1163                 }
1164             }
1165         }
1166     }
1167     catch(...)
1168     {
1169         return sal_False;
1170     }
1171     return sal_False;
1172 }
1173 
1174 /**
1175    * Judge if a XAccessible object has ManageDescendant event.
1176    * @param pAccessible XAccessible interface.
1177    * @return If XAccessible object is managedescendant.
1178    */
1179 bool AccObjectWinManager::IsStateManageDescendant(XAccessible* pAccessible)
1180 {
1181     if(pAccessible)
1182     {
1183         Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
1184         if(xContext.is())
1185         {
1186             Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
1187             if( !pRState.is() )
1188                 return sal_False;
1189 
1190             Sequence<short> pStates = pRState->getStates();
1191             int count = pStates.getLength();
1192             for( int iIndex = 0;iIndex < count;iIndex++ )
1193             {
1194                 if(pStates[iIndex] == /*AccessibleStateType::*/MANAGES_DESCENDANTS)
1195                     return sal_True;
1196             }
1197         }
1198     }
1199     return sal_False;
1200 }
1201 
1202 /**
1203    * Query and get IAccessible interface by XAccessible interface from list.
1204    * @param pXAcc XAccessible interface.
1205    * @return Com accobject interface.
1206    */
1207 IMAccessible* AccObjectWinManager::GetIMAccByXAcc(XAccessible* pXAcc)
1208 {
1209     AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
1210     if(pAccObj)
1211     {
1212         return pAccObj->GetIMAccessible();
1213     }
1214     else
1215     {
1216         return NULL;
1217     }
1218 }
1219 
1220 /**
1221    * Query and get IAccessible interface by child id from list.
1222    * @param resID, childID.
1223    * @return Com accobject interface.
1224    */
1225 IMAccessible * AccObjectWinManager::GetIAccessibleFromResID(long resID)
1226 {
1227     XResIdToAccObjHash::iterator pIndTemp = XResIdAccList.find( resID );
1228     if ( pIndTemp == XResIdAccList.end() )
1229         return NULL;
1230 
1231     AccObject* pObj = pIndTemp->second;
1232 
1233     if(pObj->GetIMAccessible())
1234         return pObj->GetIMAccessible();
1235     return NULL;
1236 }
1237 /**
1238    * Notify some object will be destroyed.
1239    * @param pXAcc XAccessible interface.
1240    * @return Com accobject interface.
1241    */
1242 void AccObjectWinManager::NotifyDestroy(XAccessible* pXAcc)
1243 {
1244     AccObject* accObj = GetAccObjByXAcc(pXAcc);
1245     if(accObj)
1246     {
1247         accObj->NotifyDestroy(sal_True);
1248     }
1249 }
1250 
1251 
1252 void AccObjectWinManager::UpdateChildState(com::sun::star::accessibility::XAccessible* pAccSubMenu)
1253 {
1254     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY);
1255     if (!xContext.is())
1256     {
1257         return;
1258     }
1259     sal_Int32 nCount = xContext->getAccessibleChildCount();
1260     for (sal_Int32 i = 0 ; i < nCount ; ++i)
1261     {
1262         Reference<com::sun::star::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i);
1263         if (xChild.is())
1264         {
1265             AccObject *pObj =  GetAccObjByXAcc(xChild.get());
1266             if (pObj)
1267             {
1268                 pObj->UpdateState();
1269             }
1270         }
1271     }
1272 }
1273 
1274 
1275 bool AccObjectWinManager::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible* pXAcc)
1276 {
1277     if (pXAcc && oldFocus != pXAcc)
1278     {
1279         if(GetParentRole(pXAcc) == TOOL_BAR)
1280         {
1281             Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext());
1282             if (pRContext.is())
1283             {
1284                 if(pRContext->getAccessibleRole() == TOGGLE_BUTTON)
1285                 {
1286                     return true;
1287                 }
1288             }
1289         }
1290     }
1291     return false;
1292 }
1293 
1294 short AccObjectWinManager::GetRole(com::sun::star::accessibility::XAccessible* pXAcc)
1295 {
1296     assert(pXAcc != NULL);
1297     Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
1298     if(xContext.is())
1299     {
1300         return xContext->getAccessibleRole();
1301     }
1302     return -1;
1303 }
1304 
1305 XAccessible* AccObjectWinManager::GetAccDocByHWND( long pWnd )
1306 {
1307     XHWNDToDocumentHash::iterator aIter;
1308     aIter = XHWNDDocList.find( pWnd );
1309     if ( aIter != XHWNDDocList.end() )
1310     {
1311         return aIter->second;
1312     }
1313 
1314     return NULL;
1315 }
1316 
1317 XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc )
1318 {
1319     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1320     long pWnd = (long)( pAccObj->GetParentHWND() );
1321     return GetAccDocByHWND( pWnd );
1322 }
1323 
1324 bool AccObjectWinManager::IsTopWinAcc( com::sun::star::accessibility::XAccessible* pXAcc )
1325 {
1326     bool bRet = false;
1327     AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
1328     if ( pAccObj )
1329     {
1330         bRet = ( pAccObj->GetParentObj() == NULL );
1331     }
1332     return bRet;
1333 }