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