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