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