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