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