]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
No significant change
[wxWidgets.git] / src / common / wincmn.cpp
index aa805541dab4eed34953bd7f7e5afa5a6d20c4d7..be19ab6146805486781edde3e55697c457506976 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     13/07/98
 // RCS-ID:      $Id$
 // Copyright:   (c) wxWindows team
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
@@ -44,6 +44,7 @@
     #include "wx/dialog.h"
     #include "wx/msgdlg.h"
     #include "wx/statusbr.h"
+    #include "wx/dcclient.h"
 #endif //WX_PRECOMP
 
 #if wxUSE_CONSTRAINTS
     #include "wx/dnd.h"
 #endif // wxUSE_DRAG_AND_DROP
 
+#if wxUSE_ACCESSIBILITY
+    #include "wx/access.h"
+#endif
+
 #if wxUSE_HELP
     #include "wx/cshelp.h"
 #endif // wxUSE_HELP
@@ -109,7 +114,6 @@ void wxWindowBase::InitBase()
     // no window yet, no parent nor children
     m_parent = (wxWindow *)NULL;
     m_windowId = -1;
-    m_children.DeleteContents( FALSE ); // don't auto delete node data
 
     // no constraints on the minimal window size
     m_minWidth =
@@ -144,15 +148,13 @@ void wxWindowBase::InitBase()
     m_hasBgCol =
     m_hasFgCol =
     m_hasFont = FALSE;
+    
+    m_isBeingDeleted = FALSE;
 
     // no style bits
     m_exStyle =
     m_windowStyle = 0;
 
-    // an optimization for the event processing: checking this flag is much
-    // faster than using IsKindOf(CLASSINFO(wxWindow))
-    m_isWindow = TRUE;
-
 #if wxUSE_CONSTRAINTS
     // no constraints whatsoever
     m_constraints = (wxLayoutConstraints *) NULL;
@@ -179,6 +181,10 @@ void wxWindowBase::InitBase()
     m_hasCustomPalette = FALSE;
 #endif // wxUSE_PALETTE
 
+#if wxUSE_ACCESSIBILITY
+    m_accessible = NULL;
+#endif
+
     m_virtualSize = wxDefaultSize;
 
     m_minVirtualWidth =
@@ -199,11 +205,6 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
                               const wxValidator& validator,
                               const wxString& name)
 {
-    // m_isWindow is set to TRUE in wxWindowBase::Init() as well as many other
-    // member variables - check that it has been called (will catch the case
-    // when a new ctor is added which doesn't call InitWindow)
-    wxASSERT_MSG( m_isWindow, wxT("Init() must have been called before!") );
-
 #if wxUSE_STATBOX
     // wxGTK doesn't allow to create controls with static box as the parent so
     // this will result in a crash when the program is ported to wxGTK so warn
@@ -215,8 +216,14 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
                   _T("wxStaticBox can't be used as a window parent!") );
 #endif // wxUSE_STATBOX
 
+    // ids are limited to 16 bits under MSW so if you care about portability,
+    // it's not a good idea to use ids out of this range (and negative ids are
+    // reserved for wxWindows own usage)
+    wxASSERT_MSG( id == wxID_ANY || (id >= 0 && id < 32767),
+                  _T("invalid id value") );
+
     // generate a new id if the user doesn't care about it
-    m_windowId = id == -1 ? NewControlId() : id;
+    m_windowId = id == wxID_ANY ? NewControlId() : id;
 
     SetName(name);
     SetWindowStyleFlag(style);
@@ -231,7 +238,7 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
     // dialog/frame and all children will inherit it by defult
     if ( parent && (parent->GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) )
     {
-        SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
+        SetExtraStyle(GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
     }
 
     return TRUE;
@@ -255,7 +262,7 @@ wxWindowBase::~wxWindowBase()
 
     // Just in case we've loaded a top-level window via LoadNativeDialog but
     // we weren't a dialog class
-    wxTopLevelWindows.DeleteObject(this);
+    wxTopLevelWindows.DeleteObject((wxWindow*)this);
 
     wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
 
@@ -301,6 +308,11 @@ wxWindowBase::~wxWindowBase()
         delete m_tooltip;
 #endif // wxUSE_TOOLTIPS
 
+#if wxUSE_ACCESSIBILITY
+    if ( m_accessible )
+        delete m_accessible;
+#endif
+
     // reset the dangling pointer our parent window may keep to us
     if ( m_parent && m_parent->GetDefaultItem() == this )
     {
@@ -331,7 +343,7 @@ bool wxWindowBase::Close(bool force)
 
 bool wxWindowBase::DestroyChildren()
 {
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( ;; )
     {
         // we iterate until the list becomes empty
@@ -507,7 +519,7 @@ wxSize wxWindowBase::DoGetBestSize() const
         int maxX = 0,
             maxY = 0;
 
-        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
@@ -541,7 +553,7 @@ wxSize wxWindowBase::DoGetBestSize() const
         int maxX = 0,
             maxY = 0;
 
-        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
@@ -601,6 +613,12 @@ void wxWindowBase::SetSizeHints(int minW, int minH,
                                 int maxW, int maxH,
                                 int WXUNUSED(incW), int WXUNUSED(incH))
 {
+    // setting min width greater than max width leads to infinite loops under
+    // X11 and generally doesn't make any sense, so don't allow it
+    wxCHECK_RET( (minW == -1 || maxW == -1 || minW <= maxW) &&
+                    (minH == -1 || maxH == -1 || minH <= maxH),
+                 _T("min width/height must be less than max width/height!") );
+
     m_minWidth = minW;
     m_maxWidth = maxW;
     m_minHeight = minH;
@@ -634,12 +652,8 @@ wxSize wxWindowBase::DoGetVirtualSize() const
 {
     wxSize  s( GetClientSize() );
 
-    if( m_virtualSize.GetWidth() != -1 )
-        s.SetWidth( m_virtualSize.GetWidth() );
-    if( m_virtualSize.GetHeight() != -1 )
-        s.SetHeight( m_virtualSize.GetHeight() );
-
-    return s;
+    return wxSize( wxMax( m_virtualSize.GetWidth(), s.GetWidth() ),
+                   wxMax( m_virtualSize.GetHeight(), s.GetHeight() ) );
 }
 
 // ----------------------------------------------------------------------------
@@ -693,9 +707,9 @@ void wxWindowBase::AddChild(wxWindowBase *child)
     // this should never happen and it will lead to a crash later if it does
     // because RemoveChild() will remove only one node from the children list
     // and the other(s) one(s) will be left with dangling pointers in them
-    wxASSERT_MSG( !GetChildren().Find(child), _T("AddChild() called twice") );
+    wxASSERT_MSG( !GetChildren().Find((wxWindow*)child), _T("AddChild() called twice") );
 
-    GetChildren().Append(child);
+    GetChildren().Append((wxWindow*)child);
     child->SetParent(this);
 }
 
@@ -703,8 +717,8 @@ void wxWindowBase::RemoveChild(wxWindowBase *child)
 {
     wxCHECK_RET( child, wxT("can't remove a NULL child") );
 
-    GetChildren().DeleteObject(child);
-    child->SetParent((wxWindow *)NULL);
+    GetChildren().DeleteObject((wxWindow *)child);
+    child->SetParent(NULL);
 }
 
 bool wxWindowBase::Reparent(wxWindowBase *newParent)
@@ -723,7 +737,7 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent)
     }
     else
     {
-        wxTopLevelWindows.DeleteObject(this);
+        wxTopLevelWindows.DeleteObject((wxWindow *)this);
     }
 
     // add it to the new one
@@ -733,7 +747,7 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent)
     }
     else
     {
-        wxTopLevelWindows.Append(this);
+        wxTopLevelWindows.Append((wxWindow *)this);
     }
 
     return TRUE;
@@ -973,7 +987,7 @@ wxWindow *wxWindowBase::FindWindow( long id )
         return (wxWindow *)this;
 
     wxWindowBase *res = (wxWindow *)NULL;
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
@@ -989,7 +1003,7 @@ wxWindow *wxWindowBase::FindWindow( const wxString& name )
         return (wxWindow *)this;
 
     wxWindowBase *res = (wxWindow *)NULL;
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
     {
         wxWindow *child = node->GetData();
@@ -1045,7 +1059,7 @@ wxWindow *wxFindWindowRecursively(const wxWindow *parent,
             return (wxWindow *)parent;
 
         // It wasn't, so check all its children
-        for ( wxWindowList::Node * node = parent->GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
@@ -1075,7 +1089,7 @@ wxWindow *wxFindWindowHelper(const wxWindow *parent,
     }
 
     // start at very top of wx's windows
-    for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
+    for ( wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
           node;
           node = node->GetNext() )
     {
@@ -1127,7 +1141,7 @@ void wxWindowBase::MakeModal(bool modal)
     // Disable all other windows
     if ( IsTopLevel() )
     {
-        wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
+        wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
         while (node)
         {
             wxWindow *win = node->GetData();
@@ -1144,7 +1158,7 @@ bool wxWindowBase::Validate()
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
@@ -1169,7 +1183,7 @@ bool wxWindowBase::TransferDataToWindow()
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
@@ -1203,7 +1217,7 @@ bool wxWindowBase::TransferDataFromWindow()
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindow *child = node->GetData();
@@ -1394,15 +1408,15 @@ void wxWindowBase::AddConstraintReference(wxWindowBase *otherWin)
 {
     if ( !m_constraintsInvolvedIn )
         m_constraintsInvolvedIn = new wxWindowList;
-    if ( !m_constraintsInvolvedIn->Find(otherWin) )
-        m_constraintsInvolvedIn->Append(otherWin);
+    if ( !m_constraintsInvolvedIn->Find((wxWindow *)otherWin) )
+        m_constraintsInvolvedIn->Append((wxWindow *)otherWin);
 }
 
 // REMOVE back-pointer to other windows we're involved with.
 void wxWindowBase::RemoveConstraintReference(wxWindowBase *otherWin)
 {
     if ( m_constraintsInvolvedIn )
-        m_constraintsInvolvedIn->DeleteObject(otherWin);
+        m_constraintsInvolvedIn->DeleteObject((wxWindow *)otherWin);
 }
 
 // Reset any constraints that mention this window
@@ -1410,7 +1424,7 @@ void wxWindowBase::DeleteRelatedConstraints()
 {
     if ( m_constraintsInvolvedIn )
     {
-        wxWindowList::Node *node = m_constraintsInvolvedIn->GetFirst();
+        wxWindowList::compatibility_iterator node = m_constraintsInvolvedIn->GetFirst();
         while (node)
         {
             wxWindow *win = node->GetData();
@@ -1429,8 +1443,8 @@ void wxWindowBase::DeleteRelatedConstraints()
                 constr->centreY.ResetIfWin(this);
             }
 
-            wxWindowList::Node *next = node->GetNext();
-            delete node;
+            wxWindowList::compatibility_iterator next = node->GetNext();
+            m_constraintsInvolvedIn->Erase(node);
             node = next;
         }
 
@@ -1544,7 +1558,7 @@ bool wxWindowBase::DoPhase(int phase)
         int noChanges = 0;
 
         // loop over all children setting their constraints
-        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
@@ -1597,7 +1611,7 @@ void wxWindowBase::ResetConstraints()
         constr->centreY.SetDone(FALSE);
     }
 
-    wxWindowList::Node *node = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
     while (node)
     {
         wxWindow *win = node->GetData();
@@ -1639,7 +1653,7 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
 
     if ( recurse )
     {
-        wxWindowList::Node *node = GetChildren().GetFirst();
+        wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
         while (node)
         {
             wxWindow *win = node->GetData();
@@ -1755,42 +1769,46 @@ void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) co
 // do Update UI processing for child controls
 // ----------------------------------------------------------------------------
 
-// TODO: should this be implemented for the child window rather
-// than the parent? Then you can override it e.g. for wxCheckBox
-// to do the Right Thing rather than having to assume a fixed number
-// of control classes.
-void wxWindowBase::UpdateWindowUI()
+void wxWindowBase::UpdateWindowUI(long flags)
 {
-#if wxUSE_CONTROLS
     wxUpdateUIEvent event(GetId());
     event.m_eventObject = this;
 
     if ( GetEventHandler()->ProcessEvent(event) )
     {
-        if ( event.GetSetEnabled() )
-            Enable(event.GetEnabled());
+        DoUpdateWindowUI(event);
+    }
 
-        if ( event.GetSetText() )
+    if (flags & wxUPDATE_UI_RECURSE)
+    {
+        wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+        while (node)
         {
-            wxControl *control = wxDynamicCastThis(wxControl);
-            if ( control )
-            {
-#if wxUSE_TEXTCTRL
-                wxTextCtrl *text = wxDynamicCast(control, wxTextCtrl);
-                if ( text )
-                {
-                       if ( event.GetText() != text->GetValue() )
-                       text->SetValue(event.GetText());
-                }
-                else
-#endif // wxUSE_TEXTCTRL
-                               {
-                                       if ( event.GetText() != control->GetLabel() )
-                       control->SetLabel(event.GetText());
-                }
-            }
+            wxWindow* child = (wxWindow*) node->GetData();
+            child->UpdateWindowUI(flags);
+            node = node->GetNext();
         }
+    }
+}
 
+// do the window-specific processing after processing the update event
+// TODO: take specific knowledge out of this function and
+// put in each control's base class. Unfortunately we don't
+// yet have base implementation files for wxCheckBox and wxRadioButton.
+void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
+{
+    if ( event.GetSetEnabled() )
+        Enable(event.GetEnabled());
+    
+#if wxUSE_CONTROLS
+    if ( event.GetSetText() )
+    {
+        wxControl *control = wxDynamicCastThis(wxControl);
+        if ( control )
+        {
+            if ( event.GetText() != control->GetLabel() )
+                control->SetLabel(event.GetText());
+        }
 #if wxUSE_CHECKBOX
         wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
         if ( checkbox )
@@ -1808,9 +1826,26 @@ void wxWindowBase::UpdateWindowUI()
                 radiobtn->SetValue(event.GetChecked());
         }
 #endif // wxUSE_RADIOBTN
+    }    
+#endif
+}
+
+#if 0
+// call internal idle recursively
+// may be obsolete (wait until OnIdle scheme stabilises)
+void wxWindowBase::ProcessInternalIdle()
+{
+    OnInternalIdle();
+
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+    while (node)
+    {
+        wxWindow *child = node->GetData();
+        child->ProcessInternalIdle();
+        node = node->GetNext();
     }
-#endif // wxUSE_CONTROLS
 }
+#endif
 
 // ----------------------------------------------------------------------------
 // dialog units translations
@@ -1849,7 +1884,7 @@ wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
 // propagate the colour change event to the subwindows
 void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
-    wxWindowList::Node *node = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
     while ( node )
     {
         // Only propagate to non-top-level windows
@@ -1865,10 +1900,15 @@ void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
     }
 }
 
-// the default action is to populate dialog with data when it's created
+// the default action is to populate dialog with data when it's created,
+// and nudge the UI into displaying itself correctly in case
+// we've turned the wxUpdateUIEvents frequency down low.
 void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
 {
     TransferDataToWindow();
+    
+    // Update the UI at this point
+    UpdateWindowUI(wxUPDATE_UI_RECURSE);
 }
 
 // process Ctrl-Alt-mclick
@@ -1936,6 +1976,37 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
     }
 }
 
+// ----------------------------------------------------------------------------
+// accessibility
+// ----------------------------------------------------------------------------
+
+#if wxUSE_ACCESSIBILITY
+void wxWindowBase::SetAccessible(wxAccessible* accessible)
+{
+    if (m_accessible && (accessible != m_accessible))
+        delete m_accessible;
+    m_accessible = accessible;
+    if (m_accessible)
+        m_accessible->SetWindow((wxWindow*) this);
+}
+
+// Returns the accessible object, creating if necessary.
+wxAccessible* wxWindowBase::GetOrCreateAccessible()
+{
+    if (!m_accessible)
+        m_accessible = CreateAccessible();
+    return m_accessible;
+}
+
+// Override to create a specific accessible object.
+wxAccessible* wxWindowBase::CreateAccessible()
+{
+    return new wxWindowAccessible((wxWindow*) this);
+}
+
+#endif
+
+#if !wxUSE_STL
 // ----------------------------------------------------------------------------
 // list classes implementation
 // ----------------------------------------------------------------------------
@@ -1944,14 +2015,15 @@ void wxWindowListNode::DeleteData()
 {
     delete (wxWindow *)GetData();
 }
+#endif
 
 // ----------------------------------------------------------------------------
 // borders
 // ----------------------------------------------------------------------------
 
-wxBorder wxWindowBase::GetBorder() const
+wxBorder wxWindowBase::GetBorder(long flags) const
 {
-    wxBorder border = (wxBorder)(m_windowStyle & wxBORDER_MASK);
+    wxBorder border = (wxBorder)(flags & wxBORDER_MASK);
     if ( border == wxBORDER_DEFAULT )
     {
         border = GetDefaultBorder();
@@ -2038,6 +2110,82 @@ void wxWindowBase::ReleaseMouse()
                GetCapture());
 }
 
+#if wxUSE_HOTKEY
+
+bool
+wxWindowBase::RegisterHotKey(int WXUNUSED(hotkeyId),
+                             int WXUNUSED(modifiers),
+                             int WXUNUSED(keycode))
+{
+    // not implemented
+    return false;
+}
+
+bool wxWindowBase::UnregisterHotKey(int WXUNUSED(hotkeyId))
+{
+    // not implemented
+    return false;
+}
+
+#endif // wxUSE_HOTKEY
+
+void wxWindowBase::SendDestroyEvent()
+{
+    wxWindowDestroyEvent event;
+    event.SetEventObject(this);
+    event.SetId(GetId());
+    GetEventHandler()->ProcessEvent(event);
+}
+
+// ----------------------------------------------------------------------------
+// event processing
+// ----------------------------------------------------------------------------
+
+#if wxUSE_VALIDATORS
+
+bool wxWindowBase::TryValidator(wxEvent& event)
+{
+    // Can only use the validator of the window which
+    // is receiving the event
+    if ( event.GetEventObject() == this )
+    {
+        wxValidator *validator = GetValidator();
+        if ( validator && validator->ProcessEvent(event) )
+        {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+#endif // wxUSE_VALIDATORS
+
+bool wxWindowBase::TryParent(wxEvent& event)
+{
+    // carry on up the parent-child hierarchy if the propgation count hasn't
+    // reached zero yet
+    if ( event.ShouldPropagate() )
+    {
+        // honour the requests to stop propagation at this window: this is
+        // used by the dialogs, for example, to prevent processing the events
+        // from the dialog controls in the parent frame which rarely, if ever,
+        // makes sense
+        if ( !(GetExtraStyle() & wxWS_EX_BLOCK_EVENTS) )
+        {
+            wxWindow *parent = GetParent();
+            if ( parent && !parent->IsBeingDeleted() )
+            {
+                wxPropagateOnce propagateOnce(event);
+
+                return parent->GetEventHandler()->ProcessEvent(event);
+            }
+        }
+    }
+
+    return wxEvtHandler::TryParent(event);
+}
+
 // ----------------------------------------------------------------------------
 // global functions
 // ----------------------------------------------------------------------------
@@ -2050,4 +2198,419 @@ wxWindow* wxGetTopLevelParent(wxWindow *win)
     return win;
 }
 
-// vi:sts=4:sw=4:et
+#if wxUSE_ACCESSIBILITY
+// ----------------------------------------------------------------------------
+// accessible object for windows
+// ----------------------------------------------------------------------------
+
+// Can return either a child object, or an integer
+// representing the child element, starting from 1.
+wxAccStatus wxWindowAccessible::HitTest(const wxPoint& pt, int* childId, wxAccessible** childObject)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Returns the rectangle for this object (id = 0) or a child element (id > 0).
+wxAccStatus wxWindowAccessible::GetLocation(wxRect& rect, int elementId)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    wxWindow* win = NULL;
+    if (elementId == 0)
+    {
+        win = GetWindow();
+    }
+    else
+    {
+        if (elementId <= (int) GetWindow()->GetChildren().GetCount())
+        {
+            win = GetWindow()->GetChildren().Item(elementId-1)->GetData();
+        }
+        else
+            return wxACC_FAIL;
+    }
+    if (win)
+    {
+        rect = win->GetRect();
+        if (win->GetParent() && !win->IsKindOf(CLASSINFO(wxTopLevelWindow)))
+            rect.SetPosition(win->GetParent()->ClientToScreen(rect.GetPosition()));
+        return wxACC_OK;
+    }
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Navigates from fromId to toId/toObject.
+wxAccStatus wxWindowAccessible::Navigate(wxNavDir navDir, int fromId,
+                             int* toId, wxAccessible** toObject)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    switch (navDir)
+    {
+    case wxNAVDIR_FIRSTCHILD:
+        {
+            if (GetWindow()->GetChildren().GetCount() == 0)
+                return wxACC_FALSE;
+            wxWindow* childWindow = (wxWindow*) GetWindow()->GetChildren().GetFirst()->GetData();
+            *toObject = childWindow->GetOrCreateAccessible();
+
+            return wxACC_OK;
+        }
+    case wxNAVDIR_LASTCHILD:
+        {
+            if (GetWindow()->GetChildren().GetCount() == 0)
+                return wxACC_FALSE;
+            wxWindow* childWindow = (wxWindow*) GetWindow()->GetChildren().GetLast()->GetData();
+            *toObject = childWindow->GetOrCreateAccessible();
+
+            return wxACC_OK;
+        }
+    case wxNAVDIR_RIGHT:
+    case wxNAVDIR_DOWN:
+    case wxNAVDIR_NEXT:
+        {
+            wxWindowList::compatibility_iterator node =
+                wxWindowList::compatibility_iterator();
+            if (fromId == 0)
+            {
+                // Can't navigate to sibling of this window
+                // if we're a top-level window.
+                if (!GetWindow()->GetParent())
+                    return wxACC_NOT_IMPLEMENTED;
+
+                node = GetWindow()->GetParent()->GetChildren().Find(GetWindow());
+            }
+            else
+            {
+                if (fromId <= (int) GetWindow()->GetChildren().GetCount())
+                    node = GetWindow()->GetChildren().Item(fromId-1);
+            }
+
+            if (node && node->GetNext())
+            {
+                wxWindow* nextWindow = node->GetNext()->GetData();
+                *toObject = nextWindow->GetOrCreateAccessible();
+                return wxACC_OK;
+            }
+            else
+                return wxACC_FALSE;
+        }
+    case wxNAVDIR_LEFT:
+    case wxNAVDIR_UP:
+    case wxNAVDIR_PREVIOUS:
+        {
+            wxWindowList::compatibility_iterator node =
+                wxWindowList::compatibility_iterator();
+            if (fromId == 0)
+            {
+                // Can't navigate to sibling of this window
+                // if we're a top-level window.
+                if (!GetWindow()->GetParent())
+                    return wxACC_NOT_IMPLEMENTED;
+
+                node = GetWindow()->GetParent()->GetChildren().Find(GetWindow());
+            }
+            else
+            {
+                if (fromId <= (int) GetWindow()->GetChildren().GetCount())
+                    node = GetWindow()->GetChildren().Item(fromId-1);
+            }
+
+            if (node && node->GetPrevious())
+            {
+                wxWindow* previousWindow = node->GetPrevious()->GetData();
+                *toObject = previousWindow->GetOrCreateAccessible();
+                return wxACC_OK;
+            }
+            else
+                return wxACC_FALSE;
+        }
+    }
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Gets the name of the specified object.
+wxAccStatus wxWindowAccessible::GetName(int childId, wxString* name)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    wxString title;
+
+    // If a child, leave wxWindows to call the function on the actual
+    // child object.
+    if (childId > 0)
+        return wxACC_NOT_IMPLEMENTED;
+
+    // This will eventually be replaced by specialised
+    // accessible classes, one for each kind of wxWindows
+    // control or window.
+    if (GetWindow()->IsKindOf(CLASSINFO(wxButton)))
+        title = ((wxButton*) GetWindow())->GetLabel();
+    else
+        title = GetWindow()->GetName();
+    
+    if (!title.IsEmpty())
+    {
+        *name = title;
+        return wxACC_OK;
+    }
+    else
+        return wxACC_NOT_IMPLEMENTED;
+}
+
+// Gets the number of children.
+wxAccStatus wxWindowAccessible::GetChildCount(int* childId)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    *childId = (int) GetWindow()->GetChildren().GetCount();
+    return wxACC_OK;
+}
+
+// Gets the specified child (starting from 1).
+// If *child is NULL and return value is wxACC_OK,
+// this means that the child is a simple element and
+// not an accessible object.
+wxAccStatus wxWindowAccessible::GetChild(int childId, wxAccessible** child)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    if (childId == 0)
+    {
+        *child = this;
+        return wxACC_OK;
+    }
+
+    if (childId > (int) GetWindow()->GetChildren().GetCount())
+        return wxACC_FAIL;
+
+    wxWindow* childWindow = GetWindow()->GetChildren().Item(childId-1)->GetData();
+    *child = childWindow->GetOrCreateAccessible();
+    if (*child)
+        return wxACC_OK;
+    else
+        return wxACC_FAIL;
+}
+
+// Gets the parent, or NULL.
+wxAccStatus wxWindowAccessible::GetParent(wxAccessible** parent)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    wxWindow* parentWindow = GetWindow()->GetParent();
+    if (!parentWindow)
+    {
+        *parent = NULL;
+        return wxACC_OK;
+    }
+    else
+    {
+        *parent = parentWindow->GetOrCreateAccessible();
+        if (*parent)
+            return wxACC_OK;
+        else
+            return wxACC_FAIL;
+    }
+}
+
+// Performs the default action. childId is 0 (the action for this object)
+// or > 0 (the action for a child).
+// Return wxACC_NOT_SUPPORTED if there is no default action for this
+// window (e.g. an edit control).
+wxAccStatus wxWindowAccessible::DoDefaultAction(int childId)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Gets the default action for this object (0) or > 0 (the action for a child).
+// Return wxACC_OK even if there is no action. actionName is the action, or the empty
+// string if there is no action.
+// The retrieved string describes the action that is performed on an object,
+// not what the object does as a result. For example, a toolbar button that prints
+// a document has a default action of "Press" rather than "Prints the current document."
+wxAccStatus wxWindowAccessible::GetDefaultAction(int childId, wxString* actionName)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Returns the description for this object or a child.
+wxAccStatus wxWindowAccessible::GetDescription(int childId, wxString* description)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    wxString ht(GetWindow()->GetHelpText());
+    if (!ht.IsEmpty())
+    {
+        *description = ht;
+        return wxACC_OK;
+    }
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Returns help text for this object or a child, similar to tooltip text.
+wxAccStatus wxWindowAccessible::GetHelpText(int childId, wxString* helpText)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    wxString ht(GetWindow()->GetHelpText());
+    if (!ht.IsEmpty())
+    {
+        *helpText = ht;
+        return wxACC_OK;
+    }
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Returns the keyboard shortcut for this object or child.
+// Return e.g. ALT+K
+wxAccStatus wxWindowAccessible::GetKeyboardShortcut(int childId, wxString* shortcut)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Returns a role constant.
+wxAccStatus wxWindowAccessible::GetRole(int childId, wxAccRole* role)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    // If a child, leave wxWindows to call the function on the actual
+    // child object.
+    if (childId > 0)
+        return wxACC_NOT_IMPLEMENTED;
+
+    if (GetWindow()->IsKindOf(CLASSINFO(wxControl)))
+        return wxACC_NOT_IMPLEMENTED;
+#if wxUSE_STATUSBAR
+    if (GetWindow()->IsKindOf(CLASSINFO(wxStatusBar)))
+        return wxACC_NOT_IMPLEMENTED;
+#endif
+#if wxUSE_TOOLBAR
+    if (GetWindow()->IsKindOf(CLASSINFO(wxToolBar)))
+        return wxACC_NOT_IMPLEMENTED;
+#endif
+
+    //*role = wxROLE_SYSTEM_CLIENT;
+    *role = wxROLE_SYSTEM_CLIENT;
+    return wxACC_OK;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Returns a state constant.
+wxAccStatus wxWindowAccessible::GetState(int childId, long* state)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    // If a child, leave wxWindows to call the function on the actual
+    // child object.
+    if (childId > 0)
+        return wxACC_NOT_IMPLEMENTED;
+
+    if (GetWindow()->IsKindOf(CLASSINFO(wxControl)))
+        return wxACC_NOT_IMPLEMENTED;
+
+#if wxUSE_STATUSBAR
+    if (GetWindow()->IsKindOf(CLASSINFO(wxStatusBar)))
+        return wxACC_NOT_IMPLEMENTED;
+#endif
+#if wxUSE_TOOLBAR
+    if (GetWindow()->IsKindOf(CLASSINFO(wxToolBar)))
+        return wxACC_NOT_IMPLEMENTED;
+#endif
+
+    *state = 0;
+    return wxACC_OK;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Returns a localized string representing the value for the object
+// or child.
+wxAccStatus wxWindowAccessible::GetValue(int childId, wxString* strValue)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Selects the object or child.
+wxAccStatus wxWindowAccessible::Select(int childId, wxAccSelectionFlags selectFlags)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Gets the window with the keyboard focus.
+// If childId is 0 and child is NULL, no object in
+// this subhierarchy has the focus.
+// If this object has the focus, child should be 'this'.
+wxAccStatus wxWindowAccessible::GetFocus(int* childId, wxAccessible** child)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+// Gets a variant representing the selected children
+// of this object.
+// Acceptable values:
+// - a null variant (IsNull() returns TRUE)
+// - a list variant (GetType() == wxT("list")
+// - an integer representing the selected child element,
+//   or 0 if this object is selected (GetType() == wxT("long")
+// - a "void*" pointer to a wxAccessible child object
+wxAccStatus wxWindowAccessible::GetSelections(wxVariant* selections)
+{
+    wxASSERT( GetWindow() != NULL );
+    if (!GetWindow())
+        return wxACC_FAIL;
+
+    return wxACC_NOT_IMPLEMENTED;
+}
+
+#endif // wxUSE_ACCESSIBILITY