1 /////////////////////////////////////////////////////////////////////////////
2 // Name: accesstest.cpp
3 // Purpose: wxWidgets accessibility sample
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2002-02-12
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
21
22
23 // for all others, include the necessary headers (this file is usually all you
24 // need because it includes almost all "standard" wxWidgets headers)
25 #ifndef WX_PRECOMP
26 #include "wx/wx.h"
27 #endif
28
29 #if wxUSE_ACCESSIBILITY
30 #include "wx/access.h"
31 #endif // wxUSE_ACCESSIBILITY
32
33 #include "wx/splitter.h"
34 #include "wx/cshelp.h"
35
36 #ifdef __WXMSW__
37 #include "windows.h"
38 #include <ole2.h>
39 #include <oleauto.h>
40
41 #if wxUSE_ACCESSIBILITY
42 #include <oleacc.h>
43 #endif // wxUSE_ACCESSIBILITY
44
45 #include "wx/msw/ole/oleutils.h"
46 #include "wx/msw/winundef.h"
47
48 #ifndef OBJID_CLIENT
49 #define OBJID_CLIENT 0xFFFFFFFC
50 #endif
51 #endif
52
53 // ----------------------------------------------------------------------------
54 // resources
55 // ----------------------------------------------------------------------------
56
57 // the application icon (under Windows it is in resources)
58 #ifndef wxHAS_IMAGES_IN_RESOURCES
59 #include "../sample.xpm"
60 #endif
61
62 // ----------------------------------------------------------------------------
63 // private classes
64 // ----------------------------------------------------------------------------
65
66 // Define a new application type, each program should derive a class from wxApp
67 class MyApp : public wxApp
68 {
69 public:
70 // override base class virtuals
71 // ----------------------------
72
73 // this one is called on application startup and is a good place for the app
74 // initialization (doing it here and not in the ctor allows to have an error
75 // return: if OnInit() returns false, the application terminates)
76 virtual bool OnInit() wxOVERRIDE;
77
78 };
79
80 #if wxUSE_ACCESSIBILITY
81
82 // Define a new frame type: this is going to be our main frame
83 class MyFrame : public wxFrame
84 {
85 public:
86 // ctor(s)
87 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
88 long style = wxDEFAULT_FRAME_STYLE);
89
90 // event handlers (these functions should _not_ be virtual)
91 void OnQuit(wxCommandEvent& event);
92 void OnQuery(wxCommandEvent& event);
93 void OnAbout(wxCommandEvent& event);
94
95 // Log messages to the text control
96 void Log(const wxString& text);
97
98 // Recursively give information about an object
99 void LogObject(int indent, IAccessible* obj);
100
101 // Get info for a child (id > 0) or object (id == 0)
102 void GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role);
103 private:
104 wxTextCtrl* m_textCtrl;
105
106 // any class wishing to process wxWidgets events must use this macro
107 wxDECLARE_EVENT_TABLE();
108 };
109
110 // ----------------------------------------------------------------------------
111 // constants
112 // ----------------------------------------------------------------------------
113
114 // IDs for the controls and the menu commands
115 enum
116 {
117 // menu items
118 AccessTest_Quit = 1,
119
120 // query the hierarchy
121 AccessTest_Query,
122
123 // it is important for the id corresponding to the "About" command to have
124 // this standard value as otherwise it won't be handled properly under Mac
125 // (where it is special and put into the "Apple" menu)
126 AccessTest_About = wxID_ABOUT
127 };
128
129 // ----------------------------------------------------------------------------
130 // event tables and other macros for wxWidgets
131 // ----------------------------------------------------------------------------
132
133 // the event tables connect the wxWidgets events with the functions (event
134 // handlers) which process them. It can be also done at run-time, but for the
135 // simple menu events like this the static method is much simpler.
136 wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
137 EVT_MENU(AccessTest_Quit, MyFrame::OnQuit)
138 EVT_MENU(AccessTest_Query, MyFrame::OnQuery)
139 EVT_MENU(AccessTest_About, MyFrame::OnAbout)
140 wxEND_EVENT_TABLE()
141
142 #endif // wxUSE_ACCESSIBILITY
143
144 // Create a new application object: this macro will allow wxWidgets to create
145 // the application object during program execution (it's better than using a
146 // static object for many reasons) and also declares the accessor function
147 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
148 // not wxApp)
149 wxIMPLEMENT_APP(MyApp);
150
151 // ============================================================================
152 // implementation
153 // ============================================================================
154
155 // ----------------------------------------------------------------------------
156 // the application class
157 // ----------------------------------------------------------------------------
158
159 // 'Main program' equivalent: the program execution "starts" here
OnInit()160 bool MyApp::OnInit()
161 {
162 if ( !wxApp::OnInit() )
163 return false;
164
165 #if wxUSE_ACCESSIBILITY
166 // Note: JAWS for Windows will only speak the context-sensitive
167 // help if you use this help provider:
168 // wxHelpProvider::Set(new wxHelpControllerHelpProvider(m_helpController)).
169 // JAWS does not seem to be getting the help text from
170 // the wxAccessible object.
171 wxHelpProvider::Set(new wxSimpleHelpProvider());
172
173 // create the main application window
174 MyFrame *frame = new MyFrame("AccessTest wxWidgets App",
175 wxPoint(50, 50), wxSize(450, 340));
176
177 // and show it (the frames, unlike simple controls, are not shown when
178 // created initially)
179 frame->Show(true);
180
181 // success: wxApp::OnRun() will be called which will enter the main message
182 // loop and the application will run. If we returned false here, the
183 // application would exit immediately.
184 return true;
185 #else
186 wxMessageBox( "This sample has to be compiled with wxUSE_ACCESSIBILITY", "Building error", wxOK);
187 return false;
188 #endif // wxUSE_ACCESSIBILITY
189 }
190
191 #if wxUSE_ACCESSIBILITY
192
193 class FrameAccessible: public wxWindowAccessible
194 {
195 public:
FrameAccessible(wxWindow * win)196 FrameAccessible(wxWindow* win): wxWindowAccessible(win) {}
197
198 // Gets the name of the specified object.
GetName(int childId,wxString * name)199 virtual wxAccStatus GetName(int childId, wxString* name) wxOVERRIDE
200 {
201 if (childId == wxACC_SELF)
202 {
203 * name = "Julian's Frame";
204 return wxACC_OK;
205 }
206 else
207 return wxACC_NOT_IMPLEMENTED;
208 }
209 };
210
211 class ScrolledWindowAccessible: public wxWindowAccessible
212 {
213 public:
ScrolledWindowAccessible(wxWindow * win)214 ScrolledWindowAccessible(wxWindow* win): wxWindowAccessible(win) {}
215
216 // Gets the name of the specified object.
GetName(int childId,wxString * name)217 virtual wxAccStatus GetName(int childId, wxString* name) wxOVERRIDE
218 {
219 if (childId == wxACC_SELF)
220 {
221 * name = "My scrolled window";
222 return wxACC_OK;
223 }
224 else
225 return wxACC_NOT_IMPLEMENTED;
226 }
227 };
228
229 class SplitterWindowAccessible: public wxWindowAccessible
230 {
231 public:
SplitterWindowAccessible(wxWindow * win)232 SplitterWindowAccessible(wxWindow* win): wxWindowAccessible(win) {}
233
234 // Gets the name of the specified object.
235 virtual wxAccStatus GetName(int childId, wxString* name) wxOVERRIDE;
236
237 // Can return either a child object, or an integer
238 // representing the child element, starting from 1.
239 virtual wxAccStatus HitTest(const wxPoint& pt, int* childId, wxAccessible** childObject) wxOVERRIDE;
240
241 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
242 virtual wxAccStatus GetLocation(wxRect& rect, int elementId) wxOVERRIDE;
243
244 // Navigates from fromId to toId/toObject.
245 virtual wxAccStatus Navigate(wxNavDir navDir, int fromId,
246 int* toId, wxAccessible** toObject) wxOVERRIDE;
247
248 // Gets the number of children.
249 virtual wxAccStatus GetChildCount(int* childCount) wxOVERRIDE;
250
251 // Gets the specified child (starting from 1).
252 // If *child is NULL and return value is wxACC_OK,
253 // this means that the child is a simple element and
254 // not an accessible object.
255 virtual wxAccStatus GetChild(int childId, wxAccessible** child) wxOVERRIDE;
256
257 // Gets the parent, or NULL.
258 virtual wxAccStatus GetParent(wxAccessible** parent) wxOVERRIDE;
259
260 // Performs the default action. childId is 0 (the action for this object)
261 // or > 0 (the action for a child).
262 // Return wxACC_NOT_SUPPORTED if there is no default action for this
263 // window (e.g. an edit control).
264 virtual wxAccStatus DoDefaultAction(int childId) wxOVERRIDE;
265
266 // Gets the default action for this object (0) or > 0 (the action for a child).
267 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
268 // string if there is no action.
269 // The retrieved string describes the action that is performed on an object,
270 // not what the object does as a result. For example, a toolbar button that prints
271 // a document has a default action of "Press" rather than "Prints the current document."
272 virtual wxAccStatus GetDefaultAction(int childId, wxString* actionName) wxOVERRIDE;
273
274 // Returns the description for this object or a child.
275 virtual wxAccStatus GetDescription(int childId, wxString* description) wxOVERRIDE;
276
277 // Returns help text for this object or a child, similar to tooltip text.
278 virtual wxAccStatus GetHelpText(int childId, wxString* helpText) wxOVERRIDE;
279
280 // Returns the keyboard shortcut for this object or child.
281 // Return e.g. ALT+K
282 virtual wxAccStatus GetKeyboardShortcut(int childId, wxString* shortcut) wxOVERRIDE;
283
284 // Returns a role constant.
285 virtual wxAccStatus GetRole(int childId, wxAccRole* role) wxOVERRIDE;
286
287 // Returns a state constant.
288 virtual wxAccStatus GetState(int childId, long* state) wxOVERRIDE;
289
290 // Returns a localized string representing the value for the object
291 // or child.
292 virtual wxAccStatus GetValue(int childId, wxString* strValue) wxOVERRIDE;
293
294 // Selects the object or child.
295 virtual wxAccStatus Select(int childId, wxAccSelectionFlags selectFlags) wxOVERRIDE;
296
297 // Gets the window with the keyboard focus.
298 // If childId is 0 and child is NULL, no object in
299 // this subhierarchy has the focus.
300 // If this object has the focus, child should be 'this'.
301 virtual wxAccStatus GetFocus(int* childId, wxAccessible** child) wxOVERRIDE;
302
303 // Gets a variant representing the selected children
304 // of this object.
305 // Acceptable values:
306 // - a null variant (IsNull() returns true)
307 // - a list variant (GetType() == "list")
308 // - an integer representing the selected child element,
309 // or 0 if this object is selected (GetType() == "long")
310 // - a "void*" pointer to a wxAccessible child object
311 virtual wxAccStatus GetSelections(wxVariant* selections) wxOVERRIDE;
312
313 };
314
315 // ----------------------------------------------------------------------------
316 // main frame
317 // ----------------------------------------------------------------------------
318
319 // frame constructor
MyFrame(const wxString & title,const wxPoint & pos,const wxSize & size,long style)320 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
321 : wxFrame(NULL, wxID_ANY, title, pos, size, style)
322 {
323 m_textCtrl = NULL;
324
325 SetAccessible(new FrameAccessible(this));
326
327 // set the frame icon
328 SetIcon(wxICON(sample));
329
330 #if wxUSE_MENUS
331 // create a menu bar
332 wxMenu *menuFile = new wxMenu;
333
334 // the "About" item should be in the help menu
335 wxMenu *helpMenu = new wxMenu;
336 helpMenu->Append(AccessTest_About, "&About", "Show about dialog");
337
338 menuFile->Append(AccessTest_Query, "Query", "Query the window hierarchy");
339 menuFile->AppendSeparator();
340 menuFile->Append(AccessTest_Quit, "E&xit\tAlt-X", "Quit this program");
341
342 // now append the freshly created menu to the menu bar...
343 wxMenuBar *menuBar = new wxMenuBar();
344 menuBar->Append(menuFile, "&File");
345 menuBar->Append(helpMenu, "&Help");
346
347 // ... and attach this menu bar to the frame
348 SetMenuBar(menuBar);
349 #endif // wxUSE_MENUS
350
351 #if 0 // wxUSE_STATUSBAR
352 // create a status bar just for fun (by default with 1 pane only)
353 CreateStatusBar(2);
354 SetStatusText("Welcome to wxWidgets!");
355 #endif // wxUSE_STATUSBAR
356
357
358 wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY);
359 splitter->SetAccessible(new SplitterWindowAccessible(splitter));
360
361 wxListBox* listBox = new wxListBox(splitter, wxID_ANY);
362 listBox->Append("Cabbages");
363 listBox->Append("Kings");
364 listBox->Append("Sealing wax");
365 listBox->Append("Strings");
366 listBox->CreateAccessible();
367 listBox->SetHelpText("This is a sample wxWidgets listbox, with a number of items in it.");
368
369 m_textCtrl = new wxTextCtrl(splitter, wxID_ANY, "", wxDefaultPosition,
370 wxDefaultSize, wxTE_MULTILINE);
371 m_textCtrl->CreateAccessible();
372 m_textCtrl->SetHelpText("This is a sample wxWidgets multiline text control.");
373
374 splitter->SplitHorizontally(listBox, m_textCtrl, 150);
375
376 #if 0
377 wxScrolledWindow* scrolledWindow = new wxScrolledWindow(this, wxID_ANY);
378 scrolledWindow->SetAccessible(new ScrolledWindowAccessible(scrolledWindow));
379 #endif
380 }
381
382
383 // event handlers
384
OnQuit(wxCommandEvent & WXUNUSED (event))385 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
386 {
387 // true is to force the frame to close
388 Close(true);
389 }
390
OnAbout(wxCommandEvent & WXUNUSED (event))391 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
392 {
393 wxString msg;
394 msg.Printf( "This is the About dialog of the AccessTest sample.\n"
395 "Welcome to %s", wxVERSION_STRING);
396
397 wxMessageBox(msg, "About AccessTest", wxOK | wxICON_INFORMATION, this);
398 }
399
OnQuery(wxCommandEvent & WXUNUSED (event))400 void MyFrame::OnQuery(wxCommandEvent& WXUNUSED(event))
401 {
402 m_textCtrl->Clear();
403 IAccessible* accessibleFrame = NULL;
404 if (S_OK != AccessibleObjectFromWindow((HWND) GetHWND(), (DWORD)OBJID_CLIENT,
405 IID_IAccessible, (void**) & accessibleFrame))
406 {
407 Log("Could not get object.");
408 return;
409 }
410 if (accessibleFrame)
411 {
412 //Log("Got an IAccessible for the frame.");
413 LogObject(0, accessibleFrame);
414 Log("Checking children using AccessibleChildren()...");
415
416 // Now check the AccessibleChildren function works OK
417 long childCount = 0;
418 if (S_OK != accessibleFrame->get_accChildCount(& childCount))
419 {
420 Log("Could not get number of children.");
421 accessibleFrame->Release();
422 return;
423 }
424 else if (childCount == 0)
425 {
426 Log("No children.");
427 accessibleFrame->Release();
428 return;
429 }
430
431
432 long obtained = 0;
433 VARIANT *var = new VARIANT[childCount];
434 int i;
435 for (i = 0; i < childCount; i++)
436 {
437 VariantInit(& (var[i]));
438 var[i].vt = VT_DISPATCH;
439 }
440
441 if (S_OK == AccessibleChildren(accessibleFrame, 0, childCount, var, &obtained))
442 {
443 for (i = 0; i < childCount; i++)
444 {
445 IAccessible* childAccessible = NULL;
446 if (var[i].pdispVal)
447 {
448 if (var[i].pdispVal->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
449 {
450 var[i].pdispVal->Release();
451
452 wxString name, role;
453 GetInfo(childAccessible, 0, name, role);
454 wxString str;
455 str.Printf("Found child %s/%s", name, role);
456 Log(str);
457 childAccessible->Release();
458 }
459 else
460 {
461 var[i].pdispVal->Release();
462 }
463 }
464 }
465 }
466 else
467 {
468 Log("AccessibleChildren failed.");
469 }
470 delete[] var;
471
472
473 accessibleFrame->Release();
474 }
475 }
476
477 // Log messages to the text control
Log(const wxString & text)478 void MyFrame::Log(const wxString& text)
479 {
480 if (m_textCtrl)
481 {
482 wxString text2(text);
483 text2.Replace("\n", " ");
484 text2.Replace("\r", " ");
485 m_textCtrl->SetInsertionPointEnd();
486 m_textCtrl->WriteText(text2 + "\n");
487 }
488 }
489
490 // Recursively give information about an object
LogObject(int indent,IAccessible * obj)491 void MyFrame::LogObject(int indent, IAccessible* obj)
492 {
493 wxString name, role;
494 if (indent == 0)
495 {
496 GetInfo(obj, 0, name, role);
497
498 wxString str;
499 str.Printf("Name = %s; Role = %s", name, role);
500 str.Pad(indent, ' ', false);
501 Log(str);
502 }
503
504 long childCount = 0;
505 if (S_OK == obj->get_accChildCount(& childCount))
506 {
507 wxString str;
508 str.Printf("There are %d children.", (int) childCount);
509 str.Pad(indent, ' ', false);
510 Log(str);
511 Log("");
512 }
513
514 int i;
515 for (i = 1; i <= childCount; i++)
516 {
517 GetInfo(obj, i, name, role);
518
519 wxString str;
520 str.Printf("%d) Name = %s; Role = %s", i, name, role);
521 str.Pad(indent, ' ', false);
522 Log(str);
523
524 VARIANT var;
525 VariantInit(& var);
526 var.vt = VT_I4;
527 var.lVal = i;
528 IDispatch* pDisp = NULL;
529 IAccessible* childObject = NULL;
530
531 if (S_OK == obj->get_accChild(var, & pDisp) && pDisp)
532 {
533 str.Printf("This is a real object.");
534 str.Pad(indent+4, ' ', false);
535 Log(str);
536
537 if (pDisp->QueryInterface(IID_IAccessible, (LPVOID*) & childObject) == S_OK)
538 {
539 LogObject(indent + 4, childObject);
540 childObject->Release();
541 }
542 pDisp->Release();
543 }
544 else
545 {
546 str.Printf("This is an element.");
547 str.Pad(indent+4, ' ', false);
548 Log(str);
549 }
550 // Log("");
551 }
552
553 }
554
555 // Get info for a child (id > 0) or object (id == 0)
GetInfo(IAccessible * accessible,int id,wxString & name,wxString & role)556 void MyFrame::GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role)
557 {
558 VARIANT var;
559 VariantInit(& var);
560 var.vt = VT_I4;
561 var.lVal = id;
562
563 BSTR bStrName = 0;
564 HRESULT hResult = accessible->get_accName(var, & bStrName);
565
566 if (hResult == S_OK)
567 {
568 name = wxConvertStringFromOle(bStrName);
569 SysFreeString(bStrName);
570 }
571 else
572 {
573 name = "NO NAME";
574 }
575
576 VARIANT varRole;
577 VariantInit(& varRole);
578
579 hResult = accessible->get_accRole(var, & varRole);
580
581 if (hResult == S_OK && varRole.vt == VT_I4)
582 {
583 wxChar buf[256];
584 GetRoleText(varRole.lVal, buf, 256);
585
586 role = buf;
587 }
588 else
589 {
590 role = "NO ROLE";
591 }
592 }
593
594 /*
595 * SplitterWindowAccessible implementation
596 */
597
598 // Gets the name of the specified object.
GetName(int childId,wxString * name)599 wxAccStatus SplitterWindowAccessible::GetName(int childId, wxString* name)
600 {
601 if (childId == wxACC_SELF)
602 {
603 * name = "Splitter window";
604 return wxACC_OK;
605 }
606 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
607 if (splitter)
608 {
609 if (splitter->IsSplit())
610 {
611 // Two windows, and the sash.
612 if (childId == 1 || childId == 3)
613 return wxACC_NOT_IMPLEMENTED;
614 else if (childId == 2)
615 {
616 *name = "Sash";
617 return wxACC_OK;
618 }
619 }
620 }
621 // Let the framework handle the other cases.
622 return wxACC_NOT_IMPLEMENTED;
623 }
624
625 // Can return either a child object, or an integer
626 // representing the child element, starting from 1.
HitTest(const wxPoint & pt,int * childId,wxAccessible ** WXUNUSED (childObject))627 wxAccStatus SplitterWindowAccessible::HitTest(const wxPoint& pt, int* childId, wxAccessible** WXUNUSED(childObject))
628 {
629 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
630 if (splitter)
631 {
632 if (splitter->IsSplit())
633 {
634 wxPoint clientPt = splitter->ScreenToClient(pt);
635 if (splitter->SashHitTest(clientPt.x, clientPt.y))
636 {
637 // We're over the sash
638 *childId = 2;
639 return wxACC_OK;
640 }
641 }
642 }
643 // Let the framework handle the other cases.
644 return wxACC_NOT_IMPLEMENTED;
645 }
646
647 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
GetLocation(wxRect & rect,int elementId)648 wxAccStatus SplitterWindowAccessible::GetLocation(wxRect& rect, int elementId)
649 {
650 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
651 if (splitter && elementId == 2 && splitter->IsSplit())
652 {
653 wxSize clientSize = splitter->GetClientSize();
654 if (splitter->GetSplitMode() == wxSPLIT_VERTICAL)
655 {
656 rect.x = splitter->GetSashPosition();
657 rect.y = 0;
658 rect.SetPosition(splitter->ClientToScreen(rect.GetPosition()));
659 rect.width = splitter->GetSashSize();
660 rect.height = clientSize.y;
661 }
662 else
663 {
664 rect.x = 0;
665 rect.y = splitter->GetSashPosition();
666 rect.SetPosition(splitter->ClientToScreen(rect.GetPosition()));
667 rect.width = clientSize.x;
668 rect.height = splitter->GetSashSize();
669 }
670 return wxACC_OK;
671 }
672 // Let the framework handle the other cases.
673 return wxACC_NOT_IMPLEMENTED;
674 }
675
676 // Navigates from fromId to toId/toObject.
Navigate(wxNavDir navDir,int fromId,int * toId,wxAccessible ** toObject)677 wxAccStatus SplitterWindowAccessible::Navigate(wxNavDir navDir, int fromId,
678 int* toId, wxAccessible** toObject)
679 {
680 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
681 if (splitter && splitter->IsSplit())
682 {
683 switch (navDir)
684 {
685 case wxNAVDIR_DOWN:
686 {
687 if (splitter->GetSplitMode() != wxSPLIT_VERTICAL)
688 {
689 if (fromId == 1)
690 {
691 *toId = 2;
692 *toObject = NULL;
693 return wxACC_OK;
694 }
695 else if (fromId == 2)
696 {
697 *toId = 3;
698 *toObject = splitter->GetWindow2()->GetAccessible();
699 return wxACC_OK;
700 }
701 }
702 return wxACC_FALSE;
703 #if 0
704 // below line is not executed due to earlier return
705 break;
706 #endif
707 }
708 case wxNAVDIR_FIRSTCHILD:
709 {
710 if (fromId == 2)
711 return wxACC_FALSE;
712 }
713 break;
714
715 case wxNAVDIR_LASTCHILD:
716 {
717 if (fromId == 2)
718 return wxACC_FALSE;
719 }
720 break;
721
722 case wxNAVDIR_LEFT:
723 {
724 if (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL)
725 {
726 if (fromId == 3)
727 {
728 *toId = 2;
729 *toObject = NULL;
730 return wxACC_OK;
731 }
732 else if (fromId == 2)
733 {
734 *toId = 1;
735 *toObject = splitter->GetWindow1()->GetAccessible();
736 return wxACC_OK;
737 }
738 }
739 return wxACC_FALSE;
740 }
741 #if 0
742 // below line is not executed due to earlier return
743 break;
744 #endif
745
746 case wxNAVDIR_NEXT:
747 {
748 if (fromId == 1)
749 {
750 *toId = 2;
751 *toObject = NULL;
752 return wxACC_OK;
753 }
754 else if (fromId == 2)
755 {
756 *toId = 3;
757 *toObject = splitter->GetWindow2()->GetAccessible();
758 return wxACC_OK;
759 }
760 return wxACC_FALSE;
761 }
762 #if 0
763 // below line is not executed due to earlier return
764 break;
765 #endif
766
767 case wxNAVDIR_PREVIOUS:
768 {
769 if (fromId == 3)
770 {
771 *toId = 2;
772 *toObject = NULL;
773 return wxACC_OK;
774 }
775 else if (fromId == 2)
776 {
777 *toId = 1;
778 *toObject = splitter->GetWindow1()->GetAccessible();
779 return wxACC_OK;
780 }
781 return wxACC_FALSE;
782 }
783 #if 0
784 // below line is not executed due to earlier return
785 break;
786 #endif
787
788 case wxNAVDIR_RIGHT:
789 {
790 if (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL)
791 {
792 if (fromId == 1)
793 {
794 *toId = 2;
795 *toObject = NULL;
796 return wxACC_OK;
797 }
798 else if (fromId == 2)
799 {
800 *toId = 3;
801 *toObject = splitter->GetWindow2()->GetAccessible();
802 return wxACC_OK;
803 }
804 }
805 // Can't go right spatially if split horizontally.
806 return wxACC_FALSE;
807 }
808 #if 0
809 // below line is not executed due to earlier return
810 break;
811 #endif
812
813 case wxNAVDIR_UP:
814 {
815 if (splitter->GetSplitMode() != wxSPLIT_VERTICAL)
816 {
817 if (fromId == 3)
818 {
819 *toId = 2;
820 return wxACC_OK;
821 }
822 else if (fromId == 2)
823 {
824 *toId = 1;
825 *toObject = splitter->GetWindow1()->GetAccessible();
826 return wxACC_OK;
827 }
828 }
829
830 // Can't go up spatially if split vertically.
831 return wxACC_FALSE;
832 #if 0
833 // below line is not executed due to earlier return
834 break;
835 #endif
836 }
837 }
838
839 }
840 // Let the framework handle the other cases.
841 return wxACC_NOT_IMPLEMENTED;
842 }
843
844 // Gets the number of children.
GetChildCount(int * childCount)845 wxAccStatus SplitterWindowAccessible::GetChildCount(int* childCount)
846 {
847 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
848 if (splitter)
849 {
850 if (splitter->IsSplit())
851 {
852 // Two windows, and the sash.
853 *childCount = 3;
854 return wxACC_OK;
855 }
856 else
857 {
858 // No sash -- 1 or 0 windows.
859 if (splitter->GetWindow1() || splitter->GetWindow2())
860 {
861 *childCount = 1;
862 return wxACC_OK;
863 }
864 else
865 {
866 *childCount = 0;
867 return wxACC_OK;
868 }
869 }
870 }
871 // Let the framework handle the other cases.
872 return wxACC_NOT_IMPLEMENTED;
873 }
874
875 // Gets the specified child (starting from 1).
876 // If *child is NULL and return value is wxACC_OK,
877 // this means that the child is a simple element and
878 // not an accessible object.
GetChild(int childId,wxAccessible ** child)879 wxAccStatus SplitterWindowAccessible::GetChild(int childId, wxAccessible** child)
880 {
881 if (childId == wxACC_SELF)
882 {
883 *child = this;
884 return wxACC_OK;
885 }
886
887 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
888 if (splitter)
889 {
890 if (splitter->IsSplit())
891 {
892 // Two windows, and the sash.
893 if (childId == 1)
894 {
895 *child = splitter->GetWindow1()->GetAccessible();
896 }
897 else if (childId == 2)
898 {
899 *child = NULL; // Sash
900 }
901 else if (childId == 3)
902 {
903 *child = splitter->GetWindow2()->GetAccessible();
904 }
905 else
906 {
907 return wxACC_FAIL;
908 }
909 return wxACC_OK;
910 }
911 else
912 {
913 // No sash -- 1 or 0 windows.
914 if (childId == 1)
915 {
916 if (splitter->GetWindow1())
917 {
918 *child = splitter->GetWindow1()->GetAccessible();
919 return wxACC_OK;
920 }
921 else if (splitter->GetWindow2())
922 {
923 *child = splitter->GetWindow2()->GetAccessible();
924 return wxACC_OK;
925 }
926 else
927 {
928 return wxACC_FAIL;
929 }
930 }
931 else
932 return wxACC_FAIL;
933 }
934 }
935 // Let the framework handle the other cases.
936 return wxACC_NOT_IMPLEMENTED;
937 }
938
939 // Gets the parent, or NULL.
GetParent(wxAccessible ** WXUNUSED (parent))940 wxAccStatus SplitterWindowAccessible::GetParent(wxAccessible** WXUNUSED(parent))
941 {
942 return wxACC_NOT_IMPLEMENTED;
943 }
944
945 // Performs the default action. childId is 0 (the action for this object)
946 // or > 0 (the action for a child).
947 // Return wxACC_NOT_SUPPORTED if there is no default action for this
948 // window (e.g. an edit control).
DoDefaultAction(int WXUNUSED (childId))949 wxAccStatus SplitterWindowAccessible::DoDefaultAction(int WXUNUSED(childId))
950 {
951 return wxACC_NOT_IMPLEMENTED;
952 }
953
954 // Gets the default action for this object (0) or > 0 (the action for a child).
955 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
956 // string if there is no action.
957 // The retrieved string describes the action that is performed on an object,
958 // not what the object does as a result. For example, a toolbar button that prints
959 // a document has a default action of "Press" rather than "Prints the current document."
GetDefaultAction(int childId,wxString * WXUNUSED (actionName))960 wxAccStatus SplitterWindowAccessible::GetDefaultAction(int childId, wxString* WXUNUSED(actionName))
961 {
962 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
963 if (splitter && splitter->IsSplit() && childId == 2)
964 {
965 // No default action for the splitter.
966 return wxACC_FALSE;
967 }
968 // Let the framework handle the other cases.
969 return wxACC_NOT_IMPLEMENTED;
970 }
971
972 // Returns the description for this object or a child.
GetDescription(int childId,wxString * description)973 wxAccStatus SplitterWindowAccessible::GetDescription(int childId, wxString* description)
974 {
975 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
976 if (splitter)
977 {
978 if (splitter->IsSplit())
979 {
980 if (childId == 2)
981 {
982 * description = _("The splitter window sash.");
983 return wxACC_OK;
984 }
985 }
986 }
987 // Let the framework handle the other cases.
988 return wxACC_NOT_IMPLEMENTED;
989 }
990
991 // Returns help text for this object or a child, similar to tooltip text.
GetHelpText(int childId,wxString * helpText)992 wxAccStatus SplitterWindowAccessible::GetHelpText(int childId, wxString* helpText)
993 {
994 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
995 if (splitter)
996 {
997 if (splitter->IsSplit())
998 {
999 if (childId == 2)
1000 {
1001 * helpText = _("The splitter window sash.");
1002 return wxACC_OK;
1003 }
1004 }
1005 }
1006 // Let the framework handle the other cases.
1007 return wxACC_NOT_IMPLEMENTED;
1008 }
1009
1010 // Returns the keyboard shortcut for this object or child.
1011 // Return e.g. ALT+K
GetKeyboardShortcut(int childId,wxString * WXUNUSED (shortcut))1012 wxAccStatus SplitterWindowAccessible::GetKeyboardShortcut(int childId, wxString* WXUNUSED(shortcut))
1013 {
1014 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1015 if (splitter && splitter->IsSplit() && childId == 2)
1016 {
1017 // No keyboard shortcut for the splitter.
1018 return wxACC_FALSE;
1019 }
1020 // Let the framework handle the other cases.
1021 return wxACC_NOT_IMPLEMENTED;
1022 }
1023
1024 // Returns a role constant.
GetRole(int childId,wxAccRole * role)1025 wxAccStatus SplitterWindowAccessible::GetRole(int childId, wxAccRole* role)
1026 {
1027 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1028 if (splitter)
1029 {
1030 if (splitter->IsSplit())
1031 {
1032 if (childId == 2)
1033 {
1034 * role = wxROLE_SYSTEM_GRIP;
1035 return wxACC_OK;
1036 }
1037 }
1038 }
1039 // Let the framework handle the other cases.
1040 return wxACC_NOT_IMPLEMENTED;
1041 }
1042
1043 // Returns a state constant.
GetState(int childId,long * state)1044 wxAccStatus SplitterWindowAccessible::GetState(int childId, long* state)
1045 {
1046 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1047 if (splitter && splitter->IsSplit() && childId == 2)
1048 {
1049 // No particular state. Not sure what would be appropriate here.
1050 *state = wxACC_STATE_SYSTEM_UNAVAILABLE;
1051 return wxACC_OK;
1052 }
1053 // Let the framework handle the other cases.
1054 return wxACC_NOT_IMPLEMENTED;
1055 }
1056
1057 // Returns a localized string representing the value for the object
1058 // or child.
GetValue(int childId,wxString * strValue)1059 wxAccStatus SplitterWindowAccessible::GetValue(int childId, wxString* strValue)
1060 {
1061 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1062 if (splitter && splitter->IsSplit() && childId == 2)
1063 {
1064 // The sash position is the value.
1065 wxString pos;
1066 pos << splitter->GetSashPosition();
1067 *strValue = pos;
1068
1069 return wxACC_OK;
1070 }
1071 // Let the framework handle the other cases.
1072 return wxACC_NOT_IMPLEMENTED;
1073 }
1074
1075 // Selects the object or child.
Select(int childId,wxAccSelectionFlags WXUNUSED (selectFlags))1076 wxAccStatus SplitterWindowAccessible::Select(int childId, wxAccSelectionFlags WXUNUSED(selectFlags))
1077 {
1078 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1079 if (splitter && splitter->IsSplit() && childId == 2)
1080 {
1081 // Can't select the sash.
1082 return wxACC_FALSE;
1083 }
1084 // Let the framework handle the other cases.
1085 return wxACC_NOT_IMPLEMENTED;
1086 }
1087
1088 // Gets the window with the keyboard focus.
1089 // If childId is 0 and child is NULL, no object in
1090 // this subhierarchy has the focus.
1091 // If this object has the focus, child should be 'this'.
GetFocus(int * WXUNUSED (childId),wxAccessible ** WXUNUSED (child))1092 wxAccStatus SplitterWindowAccessible::GetFocus(int* WXUNUSED(childId), wxAccessible** WXUNUSED(child))
1093 {
1094 return wxACC_NOT_IMPLEMENTED;
1095 }
1096
1097 // Gets a variant representing the selected children
1098 // of this object.
1099 // Acceptable values:
1100 // - a null variant (IsNull() returns true)
1101 // - a list variant (GetType() == "list")
1102 // - an integer representing the selected child element,
1103 // or 0 if this object is selected (GetType() == "long")
1104 // - a "void*" pointer to a wxAccessible child object
GetSelections(wxVariant * WXUNUSED (selections))1105 wxAccStatus SplitterWindowAccessible::GetSelections(wxVariant* WXUNUSED(selections))
1106 {
1107 return wxACC_NOT_IMPLEMENTED;
1108 }
1109
1110 #endif // wxUSE_ACCESSIBILITY
1111