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