1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/ole/access.cpp
3 // Purpose:     implementation of wxIAccessible and wxAccessible
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     2003-02-12
7 // Copyright:   (c) 2003 Julian Smart
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 // ============================================================================
12 // declarations
13 // ============================================================================
14 
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18 
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21 
22 #if defined(__BORLANDC__)
23   #pragma hdrstop
24 #endif
25 
26 #if wxUSE_OLE && wxUSE_ACCESSIBILITY
27 
28 #include "wx/access.h"
29 
30 #ifndef WX_PRECOMP
31     #include "wx/msw/wrapwin.h"
32     #include "wx/window.h"
33     #include "wx/log.h"
34 #endif
35 
36 // for some compilers, the entire ole2.h must be included, not only oleauto.h
37 #if wxUSE_NORLANDER_HEADERS || defined(__WATCOMC__)
38     #include <ole2.h>
39 #endif
40 
41 #include <oleauto.h>
42 #include <oleacc.h>
43 
44 #include "wx/msw/ole/oleutils.h"
45 
46 #ifndef CHILDID_SELF
47 #define CHILDID_SELF 0
48 #endif
49 
50 #ifndef OBJID_CLIENT
51 #define OBJID_CLIENT 0xFFFFFFFC
52 #endif
53 
54 // Convert to Windows role
55 int wxConvertToWindowsRole(wxAccRole wxrole);
56 
57 // Convert to Windows state
58 long wxConvertToWindowsState(long wxstate);
59 
60 // Convert to Windows selection flag
61 int wxConvertToWindowsSelFlag(wxAccSelectionFlags sel);
62 
63 // Convert from Windows selection flag
64 wxAccSelectionFlags wxConvertFromWindowsSelFlag(int sel);
65 
66 #if wxUSE_VARIANT
67 // ----------------------------------------------------------------------------
68 // wxIEnumVARIANT interface implementation
69 // ----------------------------------------------------------------------------
70 
71 class wxIEnumVARIANT : public IEnumVARIANT
72 {
73 public:
74     wxIEnumVARIANT(const wxVariant& variant);
~wxIEnumVARIANT()75     virtual ~wxIEnumVARIANT() { }
76 
77     DECLARE_IUNKNOWN_METHODS;
78 
79     // IEnumVARIANT
80     STDMETHODIMP Next(ULONG celt, VARIANT *rgelt, ULONG *pceltFetched);
81     STDMETHODIMP Skip(ULONG celt);
82     STDMETHODIMP Reset();
83     STDMETHODIMP Clone(IEnumVARIANT **ppenum);
84 
85 private:
86     wxVariant m_variant;  // List of further variants
87     int       m_nCurrent; // Current enum position
88 
89     wxDECLARE_NO_COPY_CLASS(wxIEnumVARIANT);
90 };
91 
92 // ----------------------------------------------------------------------------
93 // wxIEnumVARIANT
94 // ----------------------------------------------------------------------------
95 
96 BEGIN_IID_TABLE(wxIEnumVARIANT)
97     ADD_IID(Unknown)
98     ADD_IID(EnumVARIANT)
99 END_IID_TABLE;
100 
IMPLEMENT_IUNKNOWN_METHODS(wxIEnumVARIANT)101 IMPLEMENT_IUNKNOWN_METHODS(wxIEnumVARIANT)
102 
103 // wxVariant contains a list of further variants.
104 wxIEnumVARIANT::wxIEnumVARIANT(const wxVariant& variant)
105 {
106     m_variant = variant;
107 }
108 
Next(ULONG celt,VARIANT * rgelt,ULONG * pceltFetched)109 STDMETHODIMP wxIEnumVARIANT::Next(ULONG      celt,
110                                     VARIANT *rgelt,
111                                     ULONG     *pceltFetched)
112 {
113     wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Next"));
114 
115     if ( celt > 1 ) {
116         // we only return 1 element at a time - mainly because I'm too lazy to
117         // implement something which you're never asked for anyhow
118         return S_FALSE;
119     }
120 
121     if (m_variant.GetType() != wxT("list"))
122         return S_FALSE;
123 
124     if ( m_nCurrent < (int) m_variant.GetList().GetCount() ) {
125         if (!wxConvertVariantToOle(m_variant[m_nCurrent++], rgelt[0]))
126         {
127             return S_FALSE;
128         }
129 
130         // TODO: should we AddRef if this is an object?
131 
132         * pceltFetched = 1;
133         return S_OK;
134     }
135     else {
136         // bad index
137         return S_FALSE;
138     }
139 }
140 
Skip(ULONG celt)141 STDMETHODIMP wxIEnumVARIANT::Skip(ULONG celt)
142 {
143     wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Skip"));
144 
145     if (m_variant.GetType() != wxT("list"))
146         return S_FALSE;
147 
148     m_nCurrent += celt;
149     if ( m_nCurrent < (int) m_variant.GetList().GetCount() )
150         return S_OK;
151 
152     // no, can't skip this many elements
153     m_nCurrent -= celt;
154 
155     return S_FALSE;
156 }
157 
Reset()158 STDMETHODIMP wxIEnumVARIANT::Reset()
159 {
160     wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Reset"));
161 
162     m_nCurrent = 0;
163 
164     return S_OK;
165 }
166 
Clone(IEnumVARIANT ** ppenum)167 STDMETHODIMP wxIEnumVARIANT::Clone(IEnumVARIANT **ppenum)
168 {
169     wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Clone"));
170 
171     wxIEnumVARIANT *pNew = new wxIEnumVARIANT(m_variant);
172     pNew->AddRef();
173     *ppenum = pNew;
174 
175     return S_OK;
176 }
177 
178 #endif // wxUSE_VARIANT
179 
180 // ----------------------------------------------------------------------------
181 // wxIAccessible implementation of IAccessible interface
182 // ----------------------------------------------------------------------------
183 
184 class wxIAccessible : public IAccessible
185 {
186 public:
187     wxIAccessible(wxAccessible *pAccessible);
188 
189     // Called to indicate object should prepare to be deleted.
190     void Quiesce();
191 
192     DECLARE_IUNKNOWN_METHODS;
193 
194 // IAccessible
195 
196 // Navigation and Hierarchy
197 
198         // Retrieves the child element or child object at a given point on the screen.
199         // All visual objects support this method; sound objects do not support it.
200 
201     STDMETHODIMP accHitTest(long xLeft, long yLeft, VARIANT* pVarID);
202 
203         // Retrieves the specified object's current screen location. All visual objects must
204         // support this method; sound objects do not support it.
205 
206     STDMETHODIMP accLocation ( long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varID);
207 
208         // Traverses to another user interface element within a container and retrieves the object.
209         // All visual objects must support this method.
210 
211     STDMETHODIMP accNavigate ( long navDir, VARIANT varStart, VARIANT* pVarEnd);
212 
213         // Retrieves the address of an IDispatch interface for the specified child.
214         // All objects must support this property.
215 
216     STDMETHODIMP get_accChild ( VARIANT varChildID, IDispatch** ppDispChild);
217 
218         // Retrieves the number of children that belong to this object.
219         // All objects must support this property.
220 
221     STDMETHODIMP get_accChildCount ( long* pCountChildren);
222 
223         // Retrieves the IDispatch interface of the object's parent.
224         // All objects support this property.
225 
226     STDMETHODIMP get_accParent ( IDispatch** ppDispParent);
227 
228 // Descriptive Properties and Methods
229 
230         // Performs the object's default action. Not all objects have a default
231         // action.
232 
233     STDMETHODIMP accDoDefaultAction(VARIANT varID);
234 
235         // Retrieves a string that describes the object's default action.
236         // Not all objects have a default action.
237 
238     STDMETHODIMP get_accDefaultAction ( VARIANT varID, BSTR* pszDefaultAction);
239 
240         // Retrieves a string that describes the visual appearance of the specified object.
241         // Not all objects have a description.
242 
243     STDMETHODIMP get_accDescription ( VARIANT varID, BSTR* pszDescription);
244 
245         // Retrieves an object's Help property string.
246         // Not all objects support this property.
247 
248     STDMETHODIMP get_accHelp ( VARIANT varID, BSTR* pszHelp);
249 
250         // Retrieves the full path of the WinHelp file associated with the specified
251         // object and the identifier of the appropriate topic within that file.
252         // Not all objects support this property.
253 
254     STDMETHODIMP get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChild, long* pidTopic);
255 
256         // Retrieves the specified object's shortcut key or access key, also known as
257         // the mnemonic. All objects that have a shortcut key or access key support
258         // this property.
259 
260     STDMETHODIMP get_accKeyboardShortcut ( VARIANT varID, BSTR* pszKeyboardShortcut);
261 
262         // Retrieves the name of the specified object.
263         // All objects support this property.
264 
265     STDMETHODIMP get_accName ( VARIANT varID, BSTR* pszName);
266 
267         // Retrieves information that describes the role of the specified object.
268         // All objects support this property.
269 
270     STDMETHODIMP get_accRole ( VARIANT varID, VARIANT* pVarRole);
271 
272         // Retrieves the current state of the specified object.
273         // All objects support this property.
274 
275     STDMETHODIMP get_accState ( VARIANT varID, VARIANT* pVarState);
276 
277         // Retrieves the value of the specified object.
278         // Not all objects have a value.
279 
280     STDMETHODIMP get_accValue ( VARIANT varID, BSTR* pszValue);
281 
282 // Selection and Focus
283 
284         // Modifies the selection or moves the keyboard focus of the
285         // specified object. All objects that select or receive the
286         // keyboard focus must support this method.
287 
288     STDMETHODIMP accSelect ( long flagsSelect, VARIANT varID );
289 
290         // Retrieves the object that has the keyboard focus. All objects
291         // that receive the keyboard focus must support this property.
292 
293     STDMETHODIMP get_accFocus ( VARIANT* pVarID);
294 
295         // Retrieves the selected children of this object. All objects
296         // selected must support this property.
297 
298     STDMETHODIMP get_accSelection ( VARIANT * pVarChildren);
299 
300 // Obsolete
301 
put_accName(VARIANT WXUNUSED (varChild),BSTR WXUNUSED (szName))302     STDMETHODIMP put_accName(VARIANT WXUNUSED(varChild), BSTR WXUNUSED(szName)) { return E_FAIL; }
put_accValue(VARIANT WXUNUSED (varChild),BSTR WXUNUSED (szName))303     STDMETHODIMP put_accValue(VARIANT WXUNUSED(varChild), BSTR WXUNUSED(szName)) { return E_FAIL; }
304 
305 // IDispatch
306 
307         // Get type info
308 
309     STDMETHODIMP GetTypeInfo(unsigned int typeInfo, LCID lcid, ITypeInfo** ppTypeInfo);
310 
311         // Get type info count
312 
313     STDMETHODIMP GetTypeInfoCount(unsigned int* typeInfoCount);
314 
315         // Get ids of names
316 
317     STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** names, unsigned int cNames,
318         LCID lcid, DISPID* dispId);
319 
320         // Invoke
321 
322     STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
323                         WORD wFlags, DISPPARAMS *pDispParams,
324                         VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
325                         unsigned int *puArgErr );
326 
327 // Helpers
328 
329     // Gets the standard IAccessible interface for the given child or object.
330     // Call Release if this is non-NULL.
331     IAccessible* GetChildStdAccessible(int id);
332 
333     // Gets the IAccessible interface for the given child or object.
334     // Call Release if this is non-NULL.
335     IAccessible* GetChildAccessible(int id);
336 
337 private:
338     wxAccessible *m_pAccessible;      // pointer to C++ class we belong to
339     bool m_bQuiescing;                // Object is to be deleted
340 
341     wxDECLARE_NO_COPY_CLASS(wxIAccessible);
342 };
343 
344 // ============================================================================
345 // Implementation
346 // ============================================================================
347 
348 // ----------------------------------------------------------------------------
349 // wxIAccessible implementation
350 // ----------------------------------------------------------------------------
351 BEGIN_IID_TABLE(wxIAccessible)
352   ADD_IID(Unknown)
353   ADD_IID(Accessible)
354   ADD_IID(Dispatch)
355 END_IID_TABLE;
356 
IMPLEMENT_IUNKNOWN_METHODS(wxIAccessible)357 IMPLEMENT_IUNKNOWN_METHODS(wxIAccessible)
358 
359 wxIAccessible::wxIAccessible(wxAccessible *pAccessible)
360 {
361     wxASSERT( pAccessible != NULL );
362 
363     m_pAccessible = pAccessible;
364     m_bQuiescing = false;
365 }
366 
367 // Called to indicate object should prepare to be deleted.
368 
Quiesce()369 void wxIAccessible::Quiesce()
370 {
371     m_bQuiescing = true;
372     m_pAccessible = NULL;
373 }
374 
375 // Retrieves the child element or child object at a given point on the screen.
376 // All visual objects support this method; sound objects do not support it.
377 
accHitTest(long xLeft,long yLeft,VARIANT * pVarID)378 STDMETHODIMP wxIAccessible::accHitTest(long xLeft, long yLeft, VARIANT* pVarID)
379 {
380     wxLogTrace(wxT("access"), wxT("accHitTest"));
381     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
382     if (!m_pAccessible)
383         return E_FAIL;
384 
385     wxAccessible* childObject = NULL;
386     int childId = 0;
387     VariantInit(pVarID);
388 
389     wxAccStatus status = m_pAccessible->HitTest(wxPoint(xLeft, yLeft), & childId, & childObject);
390 
391     if (status == wxACC_FAIL)
392         return E_FAIL;
393 
394     if (status == wxACC_NOT_IMPLEMENTED)
395     {
396         // Use standard interface instead.
397         IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
398         if (!stdInterface)
399             return E_NOTIMPL;
400         else
401             return stdInterface->accHitTest(xLeft, yLeft, pVarID);
402     }
403 
404     if (childObject)
405     {
406         if (childObject == m_pAccessible)
407         {
408             pVarID->vt = VT_I4;
409             pVarID->lVal = CHILDID_SELF;
410             return S_OK;
411         }
412         else
413         {
414             wxIAccessible* childIA = childObject->GetIAccessible();
415             if (!childIA)
416                 return E_NOTIMPL;
417 
418             if (childIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarID->pdispVal) != S_OK)
419                 return E_FAIL;
420 
421             pVarID->vt = VT_DISPATCH;
422             return S_OK;
423         }
424     }
425     else if (childId > 0)
426     {
427         pVarID->vt = VT_I4;
428         pVarID->lVal = childId;
429         return S_OK;
430     }
431     else
432     {
433         pVarID->vt = VT_EMPTY;
434         return S_FALSE;
435     }
436 
437     #if 0
438     // all cases above already cause some return action so below line
439     // is unreachable and cause unnecessary warning
440     return E_NOTIMPL;
441     #endif
442 }
443 
444 // Retrieves the specified object's current screen location. All visual objects must
445 // support this method; sound objects do not support it.
446 
accLocation(long * pxLeft,long * pyTop,long * pcxWidth,long * pcyHeight,VARIANT varID)447 STDMETHODIMP wxIAccessible::accLocation ( long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varID)
448 {
449     wxLogTrace(wxT("access"), wxT("accLocation"));
450     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
451     if (!m_pAccessible)
452         return E_FAIL;
453 
454     wxRect rect;
455 
456     wxAccStatus status = m_pAccessible->GetLocation(rect, varID.lVal);
457     if (status == wxACC_FAIL)
458         return E_FAIL;
459 
460     if (status == wxACC_NOT_IMPLEMENTED)
461     {
462         // Try to use child object directly.
463         if (varID.lVal > 0)
464         {
465             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
466             if (childAccessible)
467             {
468                 varID.lVal = 0;
469                 HRESULT hResult = childAccessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
470                 childAccessible->Release();
471                 return hResult;
472             }
473             else if (m_pAccessible->GetIAccessibleStd())
474                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
475         }
476         else if (m_pAccessible->GetIAccessibleStd())
477             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID);
478     }
479     else
480     {
481         *pxLeft = rect.x;
482         *pyTop = rect.y;
483         *pcxWidth = rect.width;
484         *pcyHeight = rect.height;
485         return S_OK;
486     }
487 
488     return E_NOTIMPL;
489 }
490 
491 // Traverses to another user interface element within a container and retrieves the object.
492 // All visual objects must support this method.
493 
accNavigate(long navDir,VARIANT varStart,VARIANT * pVarEnd)494 STDMETHODIMP wxIAccessible::accNavigate ( long navDir, VARIANT varStart, VARIANT* pVarEnd)
495 {
496     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
497     if (!m_pAccessible)
498         return E_FAIL;
499     wxLogTrace(wxT("access"), wxString(wxT("accNavigate for ")) + m_pAccessible->GetWindow()->GetClassInfo()->GetClassName());
500 
501     if ((varStart.vt != VT_I4 && varStart.vt != VT_EMPTY)
502                                                           #if 0
503                                                           // according to MSDN and sources varStart.vt is unsigned
504                                                           // so below line cause warning "Condition is always false"
505                                                           || varStart.vt < 0
506                                                           #endif
507                                                           )
508     {
509         wxLogTrace(wxT("access"), wxT("Invalid arg for accNavigate"));
510         return E_INVALIDARG;
511     }
512 
513     wxAccessible* elementObject = NULL;
514     int elementId = 0;
515     VariantInit(pVarEnd);
516     wxNavDir navDirWX = wxNAVDIR_FIRSTCHILD;
517 
518     wxString navStr;
519 
520     switch (navDir)
521     {
522     case NAVDIR_DOWN:
523         navDirWX = wxNAVDIR_DOWN;
524         navStr = wxT("wxNAVDIR_DOWN");
525         break;
526 
527     case NAVDIR_FIRSTCHILD:
528         navDirWX = wxNAVDIR_FIRSTCHILD;
529         navStr = wxT("wxNAVDIR_FIRSTCHILD");
530         break;
531 
532     case NAVDIR_LASTCHILD:
533         navDirWX = wxNAVDIR_LASTCHILD;
534         navStr = wxT("wxNAVDIR_LASTCHILD");
535         break;
536 
537     case NAVDIR_LEFT:
538         navDirWX = wxNAVDIR_LEFT;
539         navStr = wxT("wxNAVDIR_LEFT");
540         break;
541 
542     case NAVDIR_NEXT:
543         navDirWX = wxNAVDIR_NEXT;
544         navStr = wxT("wxNAVDIR_NEXT");
545         break;
546 
547     case NAVDIR_PREVIOUS:
548         navDirWX = wxNAVDIR_PREVIOUS;
549         navStr = wxT("wxNAVDIR_PREVIOUS");
550         break;
551 
552     case NAVDIR_RIGHT:
553         navDirWX = wxNAVDIR_RIGHT;
554         navStr = wxT("wxNAVDIR_RIGHT");
555         break;
556 
557     case NAVDIR_UP:
558         navDirWX = wxNAVDIR_UP;
559         navStr = wxT("wxNAVDIR_UP");
560         break;
561     default:
562         {
563             wxLogTrace(wxT("access"), wxT("Unknown NAVDIR symbol"));
564             break;
565         }
566     }
567     wxLogTrace(wxT("access"), navStr);
568 
569     wxAccStatus status = m_pAccessible->Navigate(navDirWX, varStart.lVal, & elementId,
570         & elementObject);
571 
572     if (status == wxACC_FAIL)
573     {
574         wxLogTrace(wxT("access"), wxT("wxAccessible::Navigate failed"));
575         return E_FAIL;
576     }
577 
578     if (status == wxACC_FALSE)
579     {
580         wxLogTrace(wxT("access"), wxT("wxAccessible::Navigate found no object in this direction"));
581         return S_FALSE;
582     }
583 
584     if (status == wxACC_NOT_IMPLEMENTED)
585     {
586         wxLogTrace(wxT("access"), wxT("Navigate not implemented"));
587 
588         // Try to use child object directly.
589         if (varStart.vt == VT_I4 && varStart.lVal > 0)
590         {
591             IAccessible* childAccessible = GetChildAccessible(varStart.lVal);
592             if (childAccessible)
593             {
594                 varStart.lVal = 0;
595                 HRESULT hResult = childAccessible->accNavigate(navDir, varStart, pVarEnd);
596                 childAccessible->Release();
597                 return hResult;
598             }
599             else if (m_pAccessible->GetIAccessibleStd())
600                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accNavigate(navDir, varStart, pVarEnd);
601         }
602         else if (m_pAccessible->GetIAccessibleStd())
603             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accNavigate(navDir, varStart, pVarEnd);
604     }
605     else
606     {
607         if (elementObject)
608         {
609             wxLogTrace(wxT("access"), wxT("Getting wxIAccessible and calling QueryInterface for Navigate"));
610             wxIAccessible* objectIA = elementObject->GetIAccessible();
611             if (!objectIA)
612             {
613                 wxLogTrace(wxT("access"), wxT("No wxIAccessible"));
614                 return E_FAIL;
615             }
616 
617             HRESULT hResult = objectIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarEnd->pdispVal);
618             if (hResult != S_OK)
619             {
620                 wxLogTrace(wxT("access"), wxT("QueryInterface failed"));
621                 return E_FAIL;
622             }
623 
624             wxLogTrace(wxT("access"), wxT("Called QueryInterface for Navigate"));
625             pVarEnd->vt = VT_DISPATCH;
626             return S_OK;
627         }
628         else if (elementId > 0)
629         {
630             wxLogTrace(wxT("access"), wxT("Returning element id from Navigate"));
631             pVarEnd->vt = VT_I4;
632             pVarEnd->lVal = elementId;
633             return S_OK;
634         }
635         else
636         {
637             wxLogTrace(wxT("access"), wxT("No object in accNavigate"));
638             pVarEnd->vt = VT_EMPTY;
639             return S_FALSE;
640         }
641     }
642 
643     wxLogTrace(wxT("access"), wxT("Failing Navigate"));
644     return E_NOTIMPL;
645 }
646 
647 // Retrieves the address of an IDispatch interface for the specified child.
648 // All objects must support this property.
649 
get_accChild(VARIANT varChildID,IDispatch ** ppDispChild)650 STDMETHODIMP wxIAccessible::get_accChild ( VARIANT varChildID, IDispatch** ppDispChild)
651 {
652     wxLogTrace(wxT("access"), wxT("get_accChild"));
653     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
654     if (!m_pAccessible)
655         return E_FAIL;
656 
657     if (varChildID.vt != VT_I4)
658     {
659         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accChild"));
660         return E_INVALIDARG;
661     }
662 
663     if (varChildID.lVal == CHILDID_SELF)
664     {
665         *ppDispChild = this;
666         AddRef();
667         return S_OK;
668     }
669 
670     wxAccessible* child = NULL;
671 
672     wxAccStatus status = m_pAccessible->GetChild(varChildID.lVal, & child);
673     if (status == wxACC_FAIL)
674     {
675         wxLogTrace(wxT("access"), wxT("GetChild failed"));
676         return E_FAIL;
677     }
678 
679     if (status == wxACC_NOT_IMPLEMENTED)
680     {
681         // Use standard interface instead.
682         IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
683         if (!stdInterface)
684             return E_NOTIMPL;
685         else
686         {
687             wxLogTrace(wxT("access"), wxT("Using standard interface for get_accChild"));
688             return stdInterface->get_accChild (varChildID, ppDispChild);
689         }
690     }
691     else
692     {
693         if (child)
694         {
695             wxIAccessible* objectIA = child->GetIAccessible();
696             if (!objectIA)
697                 return E_NOTIMPL;
698 
699             if (objectIA->QueryInterface(IID_IDispatch, (LPVOID*) ppDispChild) != S_OK)
700             {
701                 wxLogTrace(wxT("access"), wxT("QueryInterface failed in get_accChild"));
702                 return E_FAIL;
703             }
704 
705             return S_OK;
706         }
707         else
708         {
709             wxLogTrace(wxT("access"), wxT("Not an accessible object"));
710             return S_FALSE; // Indicates it's not an accessible object
711         }
712     }
713 
714     #if 0
715     // all cases above already cause some return action so below line
716     // is unreachable and cause unnecessary warning
717     return E_NOTIMPL;
718     #endif
719 }
720 
721 // Retrieves the number of children that belong to this object.
722 // All objects must support this property.
723 
get_accChildCount(long * pCountChildren)724 STDMETHODIMP wxIAccessible::get_accChildCount ( long* pCountChildren)
725 {
726     wxLogTrace(wxT("access"), wxT("get_accChildCount"));
727     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
728     if (!m_pAccessible)
729         return E_FAIL;
730 
731     int childCount = 0;
732     wxAccStatus status = m_pAccessible->GetChildCount(& childCount);
733     if (status == wxACC_FAIL)
734         return E_FAIL;
735 
736     if (status == wxACC_NOT_IMPLEMENTED)
737     {
738         // Use standard interface instead.
739         IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
740         if (!stdInterface)
741             return E_NOTIMPL;
742         else
743         {
744             wxLogTrace(wxT("access"), wxT("Using standard interface for get_accChildCount"));
745             HRESULT res = stdInterface->get_accChildCount (pCountChildren);
746             wxString str;
747             str.Printf(wxT("Number of children was %d"), (int) (*pCountChildren));
748             wxLogTrace(wxT("access"), str);
749             return res;
750         }
751     }
752     else
753     {
754         * pCountChildren = (long) childCount;
755         return S_OK;
756     }
757 
758     #if 0
759     // all cases above already cause some return action so below line
760     // is unreachable and cause unnecessary warning
761     return E_NOTIMPL;
762     #endif
763 }
764 
765 // Retrieves the IDispatch interface of the object's parent.
766 // All objects support this property.
767 
get_accParent(IDispatch ** ppDispParent)768 STDMETHODIMP wxIAccessible::get_accParent ( IDispatch** ppDispParent)
769 {
770     wxLogTrace(wxT("access"), wxT("get_accParent"));
771     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
772     if (!m_pAccessible)
773         return E_FAIL;
774 
775     wxAccessible* parent = NULL;
776     wxAccStatus status = m_pAccessible->GetParent(& parent);
777 
778     if (status == wxACC_FAIL)
779         return E_FAIL;
780 
781     // It doesn't seem acceptable to return S_FALSE with a NULL
782     // ppDispParent, so if we have no wxWidgets parent, we leave
783     // it to the standard interface.
784     if (status == wxACC_NOT_IMPLEMENTED || !parent)
785     {
786         wxLogTrace(wxT("access"), wxT("Using standard interface to get the parent."));
787         // Use standard interface instead.
788         IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
789         if (!stdInterface)
790             return E_NOTIMPL;
791         else
792             return stdInterface->get_accParent (ppDispParent);
793     }
794     else
795     {
796         if (parent)
797         {
798             wxIAccessible* objectIA = parent->GetIAccessible();
799             if (!objectIA)
800                 return E_FAIL;
801 
802             wxLogTrace(wxT("access"), wxT("About to call QueryInterface"));
803             if (objectIA->QueryInterface(IID_IDispatch, (LPVOID*) ppDispParent) != S_OK)
804             {
805                 wxLogTrace(wxT("access"), wxT("Failed QueryInterface"));
806                 return E_FAIL;
807             }
808 
809             wxLogTrace(wxT("access"), wxT("Returning S_OK for get_accParent"));
810             return S_OK;
811         }
812         else
813         {
814             // This doesn't seem to be allowed, despite the documentation,
815             // so we handle it higher up by using the standard interface.
816             wxLogTrace(wxT("access"), wxT("Returning NULL parent because there was none"));
817             *ppDispParent = NULL;
818             return S_FALSE;
819         }
820     }
821 
822     #if 0
823     // all cases above already cause some return action so below line
824     // is unreachable and cause unnecessary warning
825     return E_NOTIMPL;
826     #endif
827 }
828 
829 // Performs the object's default action. Not all objects have a default
830 // action.
831 
accDoDefaultAction(VARIANT varID)832 STDMETHODIMP wxIAccessible::accDoDefaultAction(VARIANT varID)
833 {
834     wxLogTrace(wxT("access"), wxT("accDoDefaultAction"));
835     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
836     if (!m_pAccessible)
837         return E_FAIL;
838 
839     if (varID.vt != VT_I4)
840     {
841         wxLogTrace(wxT("access"), wxT("Invalid arg for accDoDefaultAction"));
842         return E_INVALIDARG;
843     }
844 
845     wxAccStatus status = m_pAccessible->DoDefaultAction(varID.lVal);
846     if (status == wxACC_FAIL)
847         return E_FAIL;
848 
849     if (status == wxACC_NOT_SUPPORTED)
850         return DISP_E_MEMBERNOTFOUND;
851 
852     if (status == wxACC_NOT_IMPLEMENTED)
853     {
854         // Try to use child object directly.
855         if (varID.lVal > 0)
856         {
857             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
858             if (childAccessible)
859             {
860                 varID.lVal = 0;
861                 HRESULT hResult = childAccessible->accDoDefaultAction(varID);
862                 childAccessible->Release();
863                 return hResult;
864             }
865             else if (m_pAccessible->GetIAccessibleStd())
866                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accDoDefaultAction(varID);
867         }
868         else if (m_pAccessible->GetIAccessibleStd())
869             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accDoDefaultAction(varID);
870     }
871     return E_FAIL;
872 }
873 
874 // Retrieves a string that describes the object's default action.
875 // Not all objects have a default action.
876 
get_accDefaultAction(VARIANT varID,BSTR * pszDefaultAction)877 STDMETHODIMP wxIAccessible::get_accDefaultAction ( VARIANT varID, BSTR* pszDefaultAction)
878 {
879     wxLogTrace(wxT("access"), wxT("get_accDefaultAction"));
880     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
881     if (!m_pAccessible)
882         return E_FAIL;
883 
884     if (varID.vt != VT_I4)
885     {
886         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accDefaultAction"));
887         return E_INVALIDARG;
888     }
889 
890     wxString defaultAction;
891     wxAccStatus status = m_pAccessible->GetDefaultAction(varID.lVal, & defaultAction);
892     if (status == wxACC_FAIL)
893         return E_FAIL;
894 
895     if (status == wxACC_NOT_SUPPORTED)
896         return DISP_E_MEMBERNOTFOUND;
897 
898     if (status == wxACC_NOT_IMPLEMENTED)
899     {
900         // Try to use child object directly.
901         if (varID.lVal > 0)
902         {
903             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
904             if (childAccessible)
905             {
906                 varID.lVal = 0;
907                 HRESULT hResult = childAccessible->get_accDefaultAction(varID, pszDefaultAction);
908                 childAccessible->Release();
909                 return hResult;
910             }
911             else if (m_pAccessible->GetIAccessibleStd())
912                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDefaultAction(varID, pszDefaultAction);
913         }
914         else if (m_pAccessible->GetIAccessibleStd())
915             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDefaultAction(varID, pszDefaultAction);
916     }
917     else
918     {
919         if (defaultAction.IsEmpty())
920         {
921             * pszDefaultAction = NULL;
922             return S_FALSE;
923         }
924         else
925         {
926             wxBasicString basicString(defaultAction);
927             * pszDefaultAction = basicString.Get();
928             return S_OK;
929         }
930     }
931     return E_FAIL;
932 }
933 
934 // Retrieves a string that describes the visual appearance of the specified object.
935 // Not all objects have a description.
936 
get_accDescription(VARIANT varID,BSTR * pszDescription)937 STDMETHODIMP wxIAccessible::get_accDescription ( VARIANT varID, BSTR* pszDescription)
938 {
939     wxLogTrace(wxT("access"), wxT("get_accDescription"));
940     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
941     if (!m_pAccessible)
942         return E_FAIL;
943 
944     if (varID.vt != VT_I4)
945     {
946         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accDescription"));
947         return E_INVALIDARG;
948     }
949 
950     wxString description;
951     wxAccStatus status = m_pAccessible->GetDescription(varID.lVal, & description);
952     if (status == wxACC_FAIL)
953         return E_FAIL;
954 
955     if (status == wxACC_NOT_IMPLEMENTED)
956     {
957         // Try to use child object directly.
958         if (varID.lVal > 0)
959         {
960             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
961             if (childAccessible)
962             {
963                 varID.lVal = 0;
964                 HRESULT hResult = childAccessible->get_accDescription(varID, pszDescription);
965                 childAccessible->Release();
966                 return hResult;
967             }
968             else if (m_pAccessible->GetIAccessibleStd())
969                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDescription(varID, pszDescription);
970         }
971         else if (m_pAccessible->GetIAccessibleStd())
972             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accDescription(varID, pszDescription);
973     }
974     else
975     {
976         if (description.empty())
977         {
978             * pszDescription = NULL;
979             return S_FALSE;
980         }
981         else
982         {
983             wxBasicString basicString(description);
984             * pszDescription = basicString.Get();
985             return S_OK;
986         }
987     }
988     return E_NOTIMPL;
989 }
990 
991 // Retrieves an object's Help property string.
992 // Not all objects support this property.
993 
get_accHelp(VARIANT varID,BSTR * pszHelp)994 STDMETHODIMP wxIAccessible::get_accHelp ( VARIANT varID, BSTR* pszHelp)
995 {
996     wxLogTrace(wxT("access"), wxT("get_accHelp"));
997     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
998     if (!m_pAccessible)
999         return E_FAIL;
1000 
1001     if (varID.vt != VT_I4)
1002     {
1003         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accHelp"));
1004         return E_INVALIDARG;
1005     }
1006 
1007     wxString helpString;
1008     wxAccStatus status = m_pAccessible->GetHelpText(varID.lVal, & helpString);
1009     if (status == wxACC_FAIL)
1010         return E_FAIL;
1011 
1012     if (status == wxACC_NOT_IMPLEMENTED)
1013     {
1014         // Try to use child object directly.
1015         if (varID.lVal > 0)
1016         {
1017             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
1018             if (childAccessible)
1019             {
1020                 varID.lVal = 0;
1021                 HRESULT hResult = childAccessible->get_accHelp(varID, pszHelp);
1022                 childAccessible->Release();
1023                 return hResult;
1024             }
1025             else if (m_pAccessible->GetIAccessibleStd())
1026                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelp(varID, pszHelp);
1027         }
1028         else if (m_pAccessible->GetIAccessibleStd())
1029             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelp (varID, pszHelp);
1030     }
1031     else
1032     {
1033         if (helpString.empty())
1034         {
1035             * pszHelp = NULL;
1036             return S_FALSE;
1037         }
1038         else
1039         {
1040             wxBasicString basicString(helpString);
1041             * pszHelp = basicString.Get();
1042             return S_OK;
1043         }
1044     }
1045     return E_NOTIMPL;
1046 }
1047 
1048 // Retrieves the full path of the WinHelp file associated with the specified
1049 // object and the identifier of the appropriate topic within that file.
1050 // Not all objects support this property.
1051 // NOTE: not supported by wxWidgets at this time. Use
1052 // GetHelpText instead.
1053 
get_accHelpTopic(BSTR * pszHelpFile,VARIANT varChild,long * pidTopic)1054 STDMETHODIMP wxIAccessible::get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChild, long* pidTopic)
1055 {
1056     wxLogTrace(wxT("access"), wxT("get_accHelpTopic"));
1057     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1058     if (!m_pAccessible)
1059         return E_FAIL;
1060 
1061     if (varChild.vt != VT_I4)
1062     {
1063         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accHelpTopic"));
1064         return E_INVALIDARG;
1065     }
1066 
1067     wxAccStatus status = wxACC_NOT_IMPLEMENTED;
1068     if (status == wxACC_FAIL)
1069         return E_FAIL;
1070 
1071     if (status == wxACC_NOT_IMPLEMENTED)
1072     {
1073         // Try to use child object directly.
1074         if (varChild.lVal > 0)
1075         {
1076             IAccessible* childAccessible = GetChildAccessible(varChild.lVal);
1077             if (childAccessible)
1078             {
1079                 varChild.lVal = 0;
1080                 HRESULT hResult = childAccessible->get_accHelpTopic(pszHelpFile, varChild, pidTopic);
1081                 childAccessible->Release();
1082                 return hResult;
1083             }
1084             else if (m_pAccessible->GetIAccessibleStd())
1085                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelpTopic(pszHelpFile, varChild, pidTopic);
1086         }
1087         else if (m_pAccessible->GetIAccessibleStd())
1088             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accHelpTopic (pszHelpFile, varChild, pidTopic);
1089     }
1090     return E_NOTIMPL;
1091 }
1092 
1093 // Retrieves the specified object's shortcut key or access key, also known as
1094 // the mnemonic. All objects that have a shortcut key or access key support
1095 // this property.
1096 
get_accKeyboardShortcut(VARIANT varID,BSTR * pszKeyboardShortcut)1097 STDMETHODIMP wxIAccessible::get_accKeyboardShortcut ( VARIANT varID, BSTR* pszKeyboardShortcut)
1098 {
1099     wxLogTrace(wxT("access"), wxT("get_accKeyboardShortcut"));
1100     *pszKeyboardShortcut = NULL;
1101 
1102     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1103     if (!m_pAccessible)
1104         return E_FAIL;
1105 
1106     if (varID.vt != VT_I4)
1107     {
1108         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accKeyboardShortcut"));
1109         return E_INVALIDARG;
1110     }
1111 
1112     wxString keyboardShortcut;
1113     wxAccStatus status = m_pAccessible->GetKeyboardShortcut(varID.lVal, & keyboardShortcut);
1114     if (status == wxACC_FAIL)
1115         return E_FAIL;
1116 
1117     if (status == wxACC_NOT_IMPLEMENTED)
1118     {
1119         // Try to use child object directly.
1120         if (varID.lVal > 0)
1121         {
1122             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
1123             if (childAccessible)
1124             {
1125                 varID.lVal = 0;
1126                 HRESULT hResult = childAccessible->get_accKeyboardShortcut(varID, pszKeyboardShortcut);
1127                 childAccessible->Release();
1128                 return hResult;
1129             }
1130             else if (m_pAccessible->GetIAccessibleStd())
1131                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accKeyboardShortcut(varID, pszKeyboardShortcut);
1132         }
1133         else if (m_pAccessible->GetIAccessibleStd())
1134             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accKeyboardShortcut (varID, pszKeyboardShortcut);
1135     }
1136     else
1137     {
1138         if (keyboardShortcut.empty())
1139         {
1140             * pszKeyboardShortcut = NULL;
1141             return S_FALSE;
1142         }
1143         else
1144         {
1145             wxBasicString basicString(keyboardShortcut);
1146             * pszKeyboardShortcut = basicString.Get();
1147             return S_OK;
1148         }
1149     }
1150     return E_NOTIMPL;
1151 }
1152 
1153 // Retrieves the name of the specified object.
1154 // All objects support this property.
1155 
get_accName(VARIANT varID,BSTR * pszName)1156 STDMETHODIMP wxIAccessible::get_accName ( VARIANT varID, BSTR* pszName)
1157 {
1158     wxLogTrace(wxT("access"), wxT("get_accName"));
1159     *pszName = NULL;
1160 
1161     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1162     if (!m_pAccessible)
1163         return E_FAIL;
1164 
1165     if (varID.vt != VT_I4)
1166     {
1167         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accName"));
1168         return E_INVALIDARG;
1169     }
1170 
1171     wxString name;
1172 
1173     wxAccStatus status = m_pAccessible->GetName(varID.lVal, & name);
1174 
1175     if (status == wxACC_FAIL)
1176         return E_FAIL;
1177 
1178     if (status == wxACC_NOT_IMPLEMENTED)
1179     {
1180         // Try to use child object directly.
1181         if (varID.lVal > 0)
1182         {
1183             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
1184             if (childAccessible)
1185             {
1186                 varID.lVal = 0;
1187                 HRESULT hResult = childAccessible->get_accName(varID, pszName);
1188                 childAccessible->Release();
1189                 return hResult;
1190             }
1191             else if (m_pAccessible->GetIAccessibleStd())
1192                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accName(varID, pszName);
1193         }
1194         else if (m_pAccessible->GetIAccessibleStd())
1195             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accName (varID, pszName);
1196     }
1197     else
1198     {
1199         wxBasicString basicString(name);
1200         *pszName = basicString.Get();
1201         return S_OK;
1202     }
1203     return E_NOTIMPL;
1204 }
1205 
1206 // Retrieves information that describes the role of the specified object.
1207 // All objects support this property.
1208 
get_accRole(VARIANT varID,VARIANT * pVarRole)1209 STDMETHODIMP wxIAccessible::get_accRole ( VARIANT varID, VARIANT* pVarRole)
1210 {
1211     wxLogTrace(wxT("access"), wxT("get_accRole"));
1212     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1213     if (!m_pAccessible)
1214         return E_FAIL;
1215 
1216     if (varID.vt != VT_I4)
1217     {
1218         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accRole"));
1219         return E_INVALIDARG;
1220     }
1221 
1222     VariantInit(pVarRole);
1223 
1224     wxAccRole role = wxROLE_NONE;
1225 
1226     wxAccStatus status = m_pAccessible->GetRole(varID.lVal, & role);
1227 
1228     if (status == wxACC_FAIL)
1229         return E_FAIL;
1230 
1231     if (status == wxACC_NOT_IMPLEMENTED)
1232     {
1233         // Try to use child object directly.
1234         if (varID.lVal > 0)
1235         {
1236             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
1237             if (childAccessible)
1238             {
1239                 varID.lVal = 0;
1240                 HRESULT hResult = childAccessible->get_accRole(varID, pVarRole);
1241                 childAccessible->Release();
1242                 return hResult;
1243             }
1244             else if (m_pAccessible->GetIAccessibleStd())
1245                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accRole(varID, pVarRole);
1246         }
1247         else if (m_pAccessible->GetIAccessibleStd())
1248             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accRole (varID, pVarRole);
1249     }
1250     else
1251     {
1252         if (role == wxROLE_NONE)
1253         {
1254             pVarRole->vt = VT_EMPTY;
1255             return S_OK;
1256         }
1257 
1258         pVarRole->lVal = wxConvertToWindowsRole(role);
1259         pVarRole->vt = VT_I4;
1260 
1261         return S_OK;
1262     }
1263     return E_NOTIMPL;
1264 }
1265 
1266 // Retrieves the current state of the specified object.
1267 // All objects support this property.
1268 
get_accState(VARIANT varID,VARIANT * pVarState)1269 STDMETHODIMP wxIAccessible::get_accState ( VARIANT varID, VARIANT* pVarState)
1270 {
1271     wxLogTrace(wxT("access"), wxT("get_accState"));
1272     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1273     if (!m_pAccessible)
1274         return E_FAIL;
1275 
1276     if (varID.vt != VT_I4 && varID.vt != VT_EMPTY)
1277     {
1278         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accState"));
1279         return E_INVALIDARG;
1280     }
1281 
1282     long wxstate = 0;
1283 
1284     wxAccStatus status = m_pAccessible->GetState(varID.lVal, & wxstate);
1285     if (status == wxACC_FAIL)
1286         return E_FAIL;
1287 
1288     if (status == wxACC_NOT_IMPLEMENTED)
1289     {
1290         // Try to use child object directly.
1291         if (varID.lVal > 0)
1292         {
1293             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
1294             if (childAccessible)
1295             {
1296                 varID.lVal = 0;
1297                 HRESULT hResult = childAccessible->get_accState(varID, pVarState);
1298                 childAccessible->Release();
1299                 return hResult;
1300             }
1301             else if (m_pAccessible->GetIAccessibleStd())
1302                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accState(varID, pVarState);
1303         }
1304         else if (m_pAccessible->GetIAccessibleStd())
1305             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accState (varID, pVarState);
1306     }
1307     else
1308     {
1309         long state = wxConvertToWindowsState(wxstate);
1310         pVarState->lVal = state;
1311         pVarState->vt = VT_I4;
1312         return S_OK;
1313     }
1314     return E_NOTIMPL;
1315 }
1316 
1317 // Retrieves the value of the specified object.
1318 // Not all objects have a value.
1319 
get_accValue(VARIANT varID,BSTR * pszValue)1320 STDMETHODIMP wxIAccessible::get_accValue ( VARIANT varID, BSTR* pszValue)
1321 {
1322     wxLogTrace(wxT("access"), wxT("get_accValue"));
1323     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1324     if (!m_pAccessible)
1325         return E_FAIL;
1326 
1327     if (varID.vt != VT_I4)
1328     {
1329         wxLogTrace(wxT("access"), wxT("Invalid arg for get_accValue"));
1330         return E_INVALIDARG;
1331     }
1332 
1333     wxString strValue;
1334 
1335     wxAccStatus status = m_pAccessible->GetValue(varID.lVal, & strValue);
1336 
1337     if (status == wxACC_FAIL)
1338         return E_FAIL;
1339 
1340     if (status == wxACC_NOT_IMPLEMENTED)
1341     {
1342         // Try to use child object directly.
1343         if (varID.lVal > 0)
1344         {
1345             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
1346             if (childAccessible)
1347             {
1348                 varID.lVal = 0;
1349                 HRESULT hResult = childAccessible->get_accValue(varID, pszValue);
1350                 childAccessible->Release();
1351                 return hResult;
1352             }
1353             else if (m_pAccessible->GetIAccessibleStd())
1354                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accValue(varID, pszValue);
1355         }
1356         else if (m_pAccessible->GetIAccessibleStd())
1357             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->get_accValue (varID, pszValue);
1358     }
1359     else
1360     {
1361         wxBasicString basicString(strValue);
1362         * pszValue = basicString.Get();
1363         return S_OK;
1364     }
1365     return E_NOTIMPL;
1366 }
1367 
1368 // Modifies the selection or moves the keyboard focus of the
1369 // specified object. All objects that select or receive the
1370 // keyboard focus must support this method.
1371 
accSelect(long flagsSelect,VARIANT varID)1372 STDMETHODIMP wxIAccessible::accSelect ( long flagsSelect, VARIANT varID )
1373 {
1374     wxLogTrace(wxT("access"), wxT("get_accSelect"));
1375     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1376     if (!m_pAccessible)
1377         return E_FAIL;
1378 
1379     if (varID.vt != VT_I4 && varID.vt != VT_EMPTY)
1380     {
1381         wxLogTrace(wxT("access"), wxT("Invalid arg for accSelect"));
1382         return E_INVALIDARG;
1383     }
1384 
1385     wxAccSelectionFlags wxsel = wxConvertFromWindowsSelFlag(flagsSelect);
1386 
1387     wxAccStatus status = m_pAccessible->Select(varID.lVal, wxsel);
1388     if (status == wxACC_FAIL)
1389         return E_FAIL;
1390 
1391     if (status == wxACC_NOT_IMPLEMENTED)
1392     {
1393         // Try to use child object directly.
1394         if (varID.lVal > 0 && varID.lVal > 0)
1395         {
1396             IAccessible* childAccessible = GetChildAccessible(varID.lVal);
1397             if (childAccessible)
1398             {
1399                 varID.lVal = 0;
1400                 HRESULT hResult = childAccessible->accSelect(flagsSelect, varID);
1401                 childAccessible->Release();
1402                 return hResult;
1403             }
1404             else if (m_pAccessible->GetIAccessibleStd())
1405                 return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accSelect(flagsSelect, varID);
1406         }
1407         else if (m_pAccessible->GetIAccessibleStd())
1408             return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accSelect(flagsSelect, varID);
1409     }
1410     else
1411         return S_OK;
1412 
1413     return E_NOTIMPL;
1414 }
1415 
1416 // Retrieves the object that has the keyboard focus. All objects
1417 // that receive the keyboard focus must support this property.
1418 
get_accFocus(VARIANT * pVarID)1419 STDMETHODIMP wxIAccessible::get_accFocus ( VARIANT* pVarID)
1420 {
1421     wxLogTrace(wxT("access"), wxT("get_accFocus"));
1422     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1423     if (!m_pAccessible)
1424         return E_FAIL;
1425 
1426     wxAccessible* childObject = NULL;
1427     int childId = 0;
1428     VariantInit(pVarID);
1429 
1430     wxAccStatus status = m_pAccessible->GetFocus(& childId, & childObject);
1431     if (status == wxACC_FAIL)
1432         return E_FAIL;
1433 
1434     if (status == wxACC_NOT_IMPLEMENTED)
1435     {
1436         // Use standard interface instead.
1437         IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
1438         if (!stdInterface)
1439             return E_NOTIMPL;
1440         else
1441             return stdInterface->get_accFocus (pVarID);
1442     }
1443     if (childObject)
1444     {
1445         if (childObject == m_pAccessible)
1446         {
1447             pVarID->vt = VT_I4;
1448             pVarID->lVal = CHILDID_SELF;
1449             return S_OK;        }
1450         else
1451         {
1452             wxIAccessible* childIA = childObject->GetIAccessible();
1453             if (!childIA)
1454                 return E_NOTIMPL;
1455 
1456             if (childIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarID->pdispVal) != S_OK)
1457                 return E_FAIL;
1458 
1459             pVarID->vt = VT_DISPATCH;
1460             return S_OK;
1461         }
1462     }
1463     else if (childId > 0)
1464     {
1465         pVarID->vt = VT_I4;
1466         pVarID->lVal = childId;
1467         return S_OK;
1468     }
1469     else
1470     {
1471         pVarID->vt = VT_EMPTY;
1472         return S_FALSE;
1473     }
1474 
1475     #if 0
1476     // all cases above already cause some return action so below line
1477     // is unreachable and cause unnecessary warning
1478     return E_NOTIMPL;
1479     #endif
1480 }
1481 
1482 // Retrieves the selected children of this object. All objects
1483 // selected must support this property.
1484 
get_accSelection(VARIANT * pVarChildren)1485 STDMETHODIMP wxIAccessible::get_accSelection ( VARIANT * pVarChildren)
1486 {
1487 #if wxUSE_VARIANT
1488     wxLogTrace(wxT("access"), wxT("get_accSelection"));
1489     wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) );
1490     if (!m_pAccessible)
1491         return E_FAIL;
1492 
1493     VariantInit(pVarChildren);
1494 
1495     wxVariant selections;
1496     wxAccStatus status = m_pAccessible->GetSelections(& selections);
1497     if (status == wxACC_FAIL)
1498         return E_FAIL;
1499 
1500     if (status == wxACC_NOT_IMPLEMENTED)
1501     {
1502         // Use standard interface instead.
1503         IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd();
1504         if (!stdInterface)
1505             return E_NOTIMPL;
1506         else
1507             return stdInterface->get_accSelection (pVarChildren);
1508     }
1509     else
1510     {
1511         if (selections.GetType() == wxT("long"))
1512         {
1513             pVarChildren->vt = VT_I4;
1514             pVarChildren->lVal = selections.GetLong();
1515 
1516             return S_OK;
1517         }
1518         else if (selections.GetType() == wxT("void*"))
1519         {
1520             wxAccessible* childObject = (wxAccessible*) selections.GetVoidPtr();
1521             wxIAccessible* childIA = childObject->GetIAccessible();
1522             if (!childIA)
1523                 return E_NOTIMPL;
1524 
1525             if (childIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarChildren->pdispVal) != S_OK)
1526                 return E_FAIL;
1527 
1528             pVarChildren->vt = VT_DISPATCH;
1529 
1530             return S_OK;
1531         }
1532         else if (selections.GetType() == wxT("list"))
1533         {
1534             // TODO: should we AddRef for every "void*" member??
1535 
1536             wxIEnumVARIANT* enumVariant = new wxIEnumVARIANT(selections);
1537             enumVariant->AddRef();
1538 
1539             pVarChildren->vt = VT_UNKNOWN;
1540             pVarChildren->punkVal = enumVariant;
1541 
1542             return S_OK;
1543         }
1544     }
1545 #else
1546     wxUnusedVar(pVarChildren);
1547 #endif // wxUSE_VARIANT
1548 
1549     return E_NOTIMPL;
1550 }
1551 
1552 // Get type info
1553 
GetTypeInfo(unsigned int WXUNUSED (typeInfo),LCID WXUNUSED (lcid),ITypeInfo ** ppTypeInfo)1554 STDMETHODIMP wxIAccessible::GetTypeInfo(unsigned int WXUNUSED(typeInfo), LCID WXUNUSED(lcid), ITypeInfo** ppTypeInfo)
1555 {
1556     *ppTypeInfo = NULL;
1557     return E_NOTIMPL;
1558 }
1559 
1560 // Get type info count
1561 
GetTypeInfoCount(unsigned int * typeInfoCount)1562 STDMETHODIMP wxIAccessible::GetTypeInfoCount(unsigned int* typeInfoCount)
1563 {
1564     *typeInfoCount = 0;
1565     return E_NOTIMPL;
1566 }
1567 
1568 // Get ids of names
1569 
GetIDsOfNames(REFIID WXUNUSED (riid),OLECHAR ** WXUNUSED (names),unsigned int WXUNUSED (cNames),LCID WXUNUSED (lcid),DISPID * WXUNUSED (dispId))1570 STDMETHODIMP wxIAccessible::GetIDsOfNames(REFIID WXUNUSED(riid), OLECHAR** WXUNUSED(names), unsigned int WXUNUSED(cNames),
1571         LCID WXUNUSED(lcid), DISPID* WXUNUSED(dispId))
1572 {
1573     return E_NOTIMPL;
1574 }
1575 
1576 // Invoke
1577 
Invoke(DISPID WXUNUSED (dispIdMember),REFIID WXUNUSED (riid),LCID WXUNUSED (lcid),WORD WXUNUSED (wFlags),DISPPARAMS * WXUNUSED (pDispParams),VARIANT * WXUNUSED (pVarResult),EXCEPINFO * WXUNUSED (pExcepInfo),unsigned int * WXUNUSED (puArgErr))1578 STDMETHODIMP wxIAccessible::Invoke(DISPID WXUNUSED(dispIdMember), REFIID WXUNUSED(riid), LCID WXUNUSED(lcid),
1579                         WORD WXUNUSED(wFlags), DISPPARAMS *WXUNUSED(pDispParams),
1580                         VARIANT *WXUNUSED(pVarResult), EXCEPINFO *WXUNUSED(pExcepInfo),
1581                         unsigned int *WXUNUSED(puArgErr) )
1582 {
1583     return E_NOTIMPL;
1584 }
1585 
1586 // Gets the standard IAccessible interface for the given child or object.
1587 // Call Release if this is non-NULL.
GetChildStdAccessible(int id)1588 IAccessible* wxIAccessible::GetChildStdAccessible(int id)
1589 {
1590     if (id == 0)
1591     {
1592         IAccessible* obj = (IAccessible*)m_pAccessible->GetIAccessibleStd();
1593 
1594         obj->AddRef();
1595         return obj;
1596     }
1597     else
1598     {
1599         VARIANT var;
1600         VariantInit(& var);
1601         var.vt = VT_I4;
1602         var.lVal = id;
1603         IDispatch* pDispatch = NULL;
1604         if (S_OK == get_accChild ( var, & pDispatch))
1605         {
1606             IAccessible* childAccessible = NULL;
1607             if (pDispatch->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
1608             {
1609                 pDispatch->Release();
1610                 wxIAccessible* c = (wxIAccessible*) childAccessible;
1611                 IAccessible* stdChildAccessible = (IAccessible*) c->m_pAccessible->GetIAccessibleStd();
1612                 stdChildAccessible->AddRef();
1613                 childAccessible->Release();
1614                 return stdChildAccessible;
1615             }
1616             else
1617             {
1618                 pDispatch->Release();
1619             }
1620         }
1621     }
1622 
1623 #if 0
1624     {
1625         // Loop until we find the right id
1626         long nChildren = 0;
1627         this->get_accChildCount(& nChildren);
1628 
1629         int i;
1630         for (i = 0; i < nChildren; i++)
1631         {
1632             long obtained = 0;
1633             VARIANT var;
1634             VariantInit(& var);
1635             var.vt = VT_I4;
1636             if (S_OK == AccessibleChildren(this, i, 1, & var, &obtained))
1637             {
1638                 if (var.lVal == id)
1639                 {
1640                     VariantInit(& var);
1641                     var.vt = VT_DISPATCH;
1642                     if (S_OK == AccessibleChildren(this, i, 1, & var, &obtained))
1643                     {
1644                         IAccessible* childAccessible = NULL;
1645                         if (var.pdispVal->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
1646                         {
1647                             var.pdispVal->Release();
1648                             return childAccessible;
1649                         }
1650                         else
1651                         {
1652                             var.pdispVal->Release();
1653                         }
1654                     }
1655                 }
1656                 break;
1657             }
1658         }
1659     }
1660 #endif
1661     return NULL;
1662 }
1663 
1664 // Gets the IAccessible interface for the given child or object.
1665 // Call Release if this is non-NULL.
GetChildAccessible(int id)1666 IAccessible* wxIAccessible::GetChildAccessible(int id)
1667 {
1668     if (id == 0)
1669     {
1670         IAccessible* obj = this;
1671 
1672         obj->AddRef();
1673         return obj;
1674     }
1675     else
1676     {
1677         VARIANT var;
1678         VariantInit(& var);
1679         var.vt = VT_I4;
1680         var.lVal = id;
1681         IDispatch* pDispatch = NULL;
1682         if (S_OK == get_accChild ( var, & pDispatch))
1683         {
1684             IAccessible* childAccessible = NULL;
1685             if (pDispatch->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
1686             {
1687                 pDispatch->Release();
1688                 return childAccessible;
1689             }
1690             else
1691             {
1692                 pDispatch->Release();
1693             }
1694         }
1695     }
1696     return NULL;
1697 }
1698 
1699 // ----------------------------------------------------------------------------
1700 // wxAccessible implementation
1701 // ----------------------------------------------------------------------------
1702 
1703 // ctors
1704 
1705 // common part of all ctors
Init()1706 void wxAccessible::Init()
1707 {
1708     m_pIAccessibleStd = NULL;
1709     m_pIAccessible = new wxIAccessible(this);
1710     m_pIAccessible->AddRef();
1711 }
1712 
wxAccessible(wxWindow * win)1713 wxAccessible::wxAccessible(wxWindow* win)
1714             : wxAccessibleBase(win)
1715 {
1716     Init();
1717 }
1718 
~wxAccessible()1719 wxAccessible::~wxAccessible()
1720 {
1721     m_pIAccessible->Quiesce();
1722     m_pIAccessible->Release();
1723     if (m_pIAccessibleStd)
1724         ((IAccessible*)m_pIAccessibleStd)->Release();
1725 }
1726 
1727 // Gets or creates a standard interface for this object.
GetIAccessibleStd()1728 void* wxAccessible::GetIAccessibleStd()
1729 {
1730     if (m_pIAccessibleStd)
1731         return m_pIAccessibleStd;
1732 
1733     if (GetWindow())
1734     {
1735         HRESULT retCode = ::CreateStdAccessibleObject((HWND) GetWindow()->GetHWND(),
1736                 OBJID_CLIENT, IID_IAccessible, (void**) & m_pIAccessibleStd);
1737         if (retCode == S_OK)
1738             return m_pIAccessibleStd;
1739         else
1740         {
1741             m_pIAccessibleStd = NULL;
1742             return NULL;
1743         }
1744     }
1745     return NULL;
1746 }
1747 
1748 // Sends an event when something changes in an accessible object.
NotifyEvent(int eventType,wxWindow * window,wxAccObject objectType,int objectId)1749 void wxAccessible::NotifyEvent(int eventType, wxWindow* window, wxAccObject objectType,
1750                         int objectId)
1751 {
1752     ::NotifyWinEvent((DWORD) eventType, (HWND) window->GetHWND(),
1753         (LONG) objectType, (LONG) objectId);
1754 }
1755 
1756 // Utilities
1757 
1758 // Convert to Windows role
wxConvertToWindowsRole(wxAccRole wxrole)1759 int wxConvertToWindowsRole(wxAccRole wxrole)
1760 {
1761     switch (wxrole)
1762     {
1763     case wxROLE_NONE:
1764         return 0;
1765     case wxROLE_SYSTEM_ALERT:
1766         return ROLE_SYSTEM_ALERT;
1767     case wxROLE_SYSTEM_ANIMATION:
1768         return ROLE_SYSTEM_ANIMATION;
1769     case wxROLE_SYSTEM_APPLICATION:
1770         return ROLE_SYSTEM_APPLICATION;
1771     case wxROLE_SYSTEM_BORDER:
1772         return ROLE_SYSTEM_BORDER;
1773     case wxROLE_SYSTEM_BUTTONDROPDOWN:
1774         return ROLE_SYSTEM_BUTTONDROPDOWN;
1775     case wxROLE_SYSTEM_BUTTONDROPDOWNGRID:
1776         return ROLE_SYSTEM_BUTTONDROPDOWNGRID;
1777     case wxROLE_SYSTEM_BUTTONMENU:
1778         return ROLE_SYSTEM_BUTTONMENU;
1779     case wxROLE_SYSTEM_CARET:
1780         return ROLE_SYSTEM_CARET;
1781     case wxROLE_SYSTEM_CELL:
1782         return ROLE_SYSTEM_CELL;
1783     case wxROLE_SYSTEM_CHARACTER:
1784         return ROLE_SYSTEM_CHARACTER;
1785     case wxROLE_SYSTEM_CHART:
1786         return ROLE_SYSTEM_CHART;
1787     case wxROLE_SYSTEM_CHECKBUTTON:
1788         return ROLE_SYSTEM_CHECKBUTTON;
1789     case wxROLE_SYSTEM_CLIENT:
1790         return ROLE_SYSTEM_CLIENT;
1791     case wxROLE_SYSTEM_CLOCK:
1792         return ROLE_SYSTEM_CLOCK;
1793     case wxROLE_SYSTEM_COLUMN:
1794         return ROLE_SYSTEM_COLUMN;
1795     case wxROLE_SYSTEM_COLUMNHEADER:
1796         return ROLE_SYSTEM_COLUMNHEADER;
1797     case wxROLE_SYSTEM_COMBOBOX:
1798         return ROLE_SYSTEM_COMBOBOX;
1799     case wxROLE_SYSTEM_CURSOR:
1800         return ROLE_SYSTEM_CURSOR;
1801     case wxROLE_SYSTEM_DIAGRAM:
1802         return ROLE_SYSTEM_DIAGRAM;
1803     case wxROLE_SYSTEM_DIAL:
1804         return ROLE_SYSTEM_DIAL;
1805     case wxROLE_SYSTEM_DIALOG:
1806         return ROLE_SYSTEM_DIALOG;
1807     case wxROLE_SYSTEM_DOCUMENT:
1808         return ROLE_SYSTEM_DOCUMENT;
1809     case wxROLE_SYSTEM_DROPLIST:
1810         return ROLE_SYSTEM_DROPLIST;
1811     case wxROLE_SYSTEM_EQUATION:
1812         return ROLE_SYSTEM_EQUATION;
1813     case wxROLE_SYSTEM_GRAPHIC:
1814         return ROLE_SYSTEM_GRAPHIC;
1815     case wxROLE_SYSTEM_GRIP:
1816         return ROLE_SYSTEM_GRIP;
1817     case wxROLE_SYSTEM_GROUPING:
1818         return ROLE_SYSTEM_GROUPING;
1819     case wxROLE_SYSTEM_HELPBALLOON:
1820         return ROLE_SYSTEM_HELPBALLOON;
1821     case wxROLE_SYSTEM_HOTKEYFIELD:
1822         return ROLE_SYSTEM_HOTKEYFIELD;
1823     case wxROLE_SYSTEM_INDICATOR:
1824         return ROLE_SYSTEM_INDICATOR;
1825     case wxROLE_SYSTEM_LINK:
1826         return ROLE_SYSTEM_LINK;
1827     case wxROLE_SYSTEM_LIST:
1828         return ROLE_SYSTEM_LIST;
1829     case wxROLE_SYSTEM_LISTITEM:
1830         return ROLE_SYSTEM_LISTITEM;
1831     case wxROLE_SYSTEM_MENUBAR:
1832         return ROLE_SYSTEM_MENUBAR;
1833     case wxROLE_SYSTEM_MENUITEM:
1834         return ROLE_SYSTEM_MENUITEM;
1835     case wxROLE_SYSTEM_MENUPOPUP:
1836         return ROLE_SYSTEM_MENUPOPUP;
1837     case wxROLE_SYSTEM_OUTLINE:
1838         return ROLE_SYSTEM_OUTLINE;
1839     case wxROLE_SYSTEM_OUTLINEITEM:
1840         return ROLE_SYSTEM_OUTLINEITEM;
1841     case wxROLE_SYSTEM_PAGETAB:
1842         return ROLE_SYSTEM_PAGETAB;
1843     case wxROLE_SYSTEM_PAGETABLIST:
1844         return ROLE_SYSTEM_PAGETABLIST;
1845     case wxROLE_SYSTEM_PANE:
1846         return ROLE_SYSTEM_PANE;
1847     case wxROLE_SYSTEM_PROGRESSBAR:
1848         return ROLE_SYSTEM_PROGRESSBAR;
1849     case wxROLE_SYSTEM_PROPERTYPAGE:
1850         return ROLE_SYSTEM_PROPERTYPAGE;
1851     case wxROLE_SYSTEM_PUSHBUTTON:
1852         return ROLE_SYSTEM_PUSHBUTTON;
1853     case wxROLE_SYSTEM_RADIOBUTTON:
1854         return ROLE_SYSTEM_RADIOBUTTON;
1855     case wxROLE_SYSTEM_ROW:
1856         return ROLE_SYSTEM_ROW;
1857     case wxROLE_SYSTEM_ROWHEADER:
1858         return ROLE_SYSTEM_ROWHEADER;
1859     case wxROLE_SYSTEM_SCROLLBAR:
1860         return ROLE_SYSTEM_SCROLLBAR;
1861     case wxROLE_SYSTEM_SEPARATOR:
1862         return ROLE_SYSTEM_SEPARATOR;
1863     case wxROLE_SYSTEM_SLIDER:
1864         return ROLE_SYSTEM_SLIDER;
1865     case wxROLE_SYSTEM_SOUND:
1866         return ROLE_SYSTEM_SOUND;
1867     case wxROLE_SYSTEM_SPINBUTTON:
1868         return ROLE_SYSTEM_SPINBUTTON;
1869     case wxROLE_SYSTEM_STATICTEXT:
1870         return ROLE_SYSTEM_STATICTEXT;
1871     case wxROLE_SYSTEM_STATUSBAR:
1872         return ROLE_SYSTEM_STATUSBAR;
1873     case wxROLE_SYSTEM_TABLE:
1874         return ROLE_SYSTEM_TABLE;
1875     case wxROLE_SYSTEM_TEXT:
1876         return ROLE_SYSTEM_TEXT;
1877     case wxROLE_SYSTEM_TITLEBAR:
1878         return ROLE_SYSTEM_TITLEBAR;
1879     case wxROLE_SYSTEM_TOOLBAR:
1880         return ROLE_SYSTEM_TOOLBAR;
1881     case wxROLE_SYSTEM_TOOLTIP:
1882         return ROLE_SYSTEM_TOOLTIP;
1883     case wxROLE_SYSTEM_WHITESPACE:
1884         return ROLE_SYSTEM_WHITESPACE;
1885     case wxROLE_SYSTEM_WINDOW:
1886         return ROLE_SYSTEM_WINDOW;
1887     }
1888     return 0;
1889 }
1890 
1891 // Convert to Windows state
wxConvertToWindowsState(long wxstate)1892 long wxConvertToWindowsState(long wxstate)
1893 {
1894     long state = 0;
1895     if (wxstate & wxACC_STATE_SYSTEM_ALERT_HIGH)
1896         state |= STATE_SYSTEM_ALERT_HIGH;
1897 
1898     if (wxstate & wxACC_STATE_SYSTEM_ALERT_MEDIUM)
1899         state |= STATE_SYSTEM_ALERT_MEDIUM;
1900 
1901     if (wxstate & wxACC_STATE_SYSTEM_ALERT_LOW)
1902         state |= STATE_SYSTEM_ALERT_LOW;
1903 
1904     if (wxstate & wxACC_STATE_SYSTEM_ANIMATED)
1905         state |= STATE_SYSTEM_ANIMATED;
1906 
1907     if (wxstate & wxACC_STATE_SYSTEM_BUSY)
1908         state |= STATE_SYSTEM_BUSY;
1909 
1910     if (wxstate & wxACC_STATE_SYSTEM_CHECKED)
1911         state |= STATE_SYSTEM_CHECKED;
1912 
1913     if (wxstate & wxACC_STATE_SYSTEM_COLLAPSED)
1914         state |= STATE_SYSTEM_COLLAPSED;
1915 
1916     if (wxstate & wxACC_STATE_SYSTEM_DEFAULT)
1917         state |= STATE_SYSTEM_DEFAULT;
1918 
1919     if (wxstate & wxACC_STATE_SYSTEM_EXPANDED)
1920         state |= STATE_SYSTEM_EXPANDED;
1921 
1922     if (wxstate & wxACC_STATE_SYSTEM_EXTSELECTABLE)
1923         state |= STATE_SYSTEM_EXTSELECTABLE;
1924 
1925     if (wxstate & wxACC_STATE_SYSTEM_FLOATING)
1926         state |= STATE_SYSTEM_FLOATING;
1927 
1928     if (wxstate & wxACC_STATE_SYSTEM_FOCUSABLE)
1929         state |= STATE_SYSTEM_FOCUSABLE;
1930 
1931     if (wxstate & wxACC_STATE_SYSTEM_FOCUSED)
1932         state |= STATE_SYSTEM_FOCUSED;
1933 
1934     if (wxstate & wxACC_STATE_SYSTEM_HOTTRACKED)
1935         state |= STATE_SYSTEM_HOTTRACKED;
1936 
1937     if (wxstate & wxACC_STATE_SYSTEM_INVISIBLE)
1938         state |= STATE_SYSTEM_INVISIBLE;
1939 
1940     if (wxstate & wxACC_STATE_SYSTEM_MARQUEED)
1941         state |= STATE_SYSTEM_MARQUEED;
1942 
1943     if (wxstate & wxACC_STATE_SYSTEM_MIXED)
1944         state |= STATE_SYSTEM_MIXED;
1945 
1946     if (wxstate & wxACC_STATE_SYSTEM_MULTISELECTABLE)
1947         state |= STATE_SYSTEM_MULTISELECTABLE;
1948 
1949     if (wxstate & wxACC_STATE_SYSTEM_OFFSCREEN)
1950         state |= STATE_SYSTEM_OFFSCREEN;
1951 
1952     if (wxstate & wxACC_STATE_SYSTEM_PRESSED)
1953         state |= STATE_SYSTEM_PRESSED;
1954 
1955 //    if (wxstate & wxACC_STATE_SYSTEM_PROTECTED)
1956 //        state |= STATE_SYSTEM_PROTECTED;
1957 
1958     if (wxstate & wxACC_STATE_SYSTEM_READONLY)
1959         state |= STATE_SYSTEM_READONLY;
1960 
1961     if (wxstate & wxACC_STATE_SYSTEM_SELECTABLE)
1962         state |= STATE_SYSTEM_SELECTABLE;
1963 
1964     if (wxstate & wxACC_STATE_SYSTEM_SELECTED)
1965         state |= STATE_SYSTEM_SELECTED;
1966 
1967     if (wxstate & wxACC_STATE_SYSTEM_SELFVOICING)
1968         state |= STATE_SYSTEM_SELFVOICING;
1969 
1970     if (wxstate & wxACC_STATE_SYSTEM_UNAVAILABLE)
1971         state |= STATE_SYSTEM_UNAVAILABLE;
1972 
1973     return state;
1974 }
1975 
1976 // Convert to Windows selection flag
wxConvertToWindowsSelFlag(wxAccSelectionFlags wxsel)1977 int wxConvertToWindowsSelFlag(wxAccSelectionFlags wxsel)
1978 {
1979     int sel = 0;
1980 
1981     if (wxsel & wxACC_SEL_TAKEFOCUS)
1982         sel |= SELFLAG_TAKEFOCUS;
1983     if (wxsel & wxACC_SEL_TAKESELECTION)
1984         sel |= SELFLAG_TAKESELECTION;
1985     if (wxsel & wxACC_SEL_EXTENDSELECTION)
1986         sel |= SELFLAG_EXTENDSELECTION;
1987     if (wxsel & wxACC_SEL_ADDSELECTION)
1988         sel |= SELFLAG_ADDSELECTION;
1989     if (wxsel & wxACC_SEL_REMOVESELECTION)
1990         sel |= SELFLAG_REMOVESELECTION;
1991     return sel;
1992 }
1993 
1994 // Convert from Windows selection flag
wxConvertFromWindowsSelFlag(int sel)1995 wxAccSelectionFlags wxConvertFromWindowsSelFlag(int sel)
1996 {
1997     int wxsel = 0;
1998 
1999     if (sel & SELFLAG_TAKEFOCUS)
2000         wxsel |= wxACC_SEL_TAKEFOCUS;
2001     if (sel & SELFLAG_TAKESELECTION)
2002         wxsel |= wxACC_SEL_TAKESELECTION;
2003     if (sel & SELFLAG_EXTENDSELECTION)
2004         wxsel |= wxACC_SEL_EXTENDSELECTION;
2005     if (sel & SELFLAG_ADDSELECTION)
2006         wxsel |= wxACC_SEL_ADDSELECTION;
2007     if (sel & SELFLAG_REMOVESELECTION)
2008         wxsel |= wxACC_SEL_REMOVESELECTION;
2009     return (wxAccSelectionFlags) wxsel;
2010 }
2011 
2012 
2013 #endif  // wxUSE_OLE && wxUSE_ACCESSIBILITY
2014