]> git.saurik.com Git - wxWidgets.git/commitdiff
keyboard/focus handling improved a bit more:
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 Jun 1999 21:51:15 +0000 (21:51 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 Jun 1999 21:51:15 +0000 (21:51 +0000)
1. wxFrame doesn't give focus to anything at all on activation
2. last control restored more often (some problems still persist)
3. buttons process enter
4. text controls with wxTE_PROCESS_TAB still leave TAB work as dialog
   navigation key if the event wasn't processed

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2842 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/panelg.h
src/common/wincmn.cpp
src/generic/panelg.cpp
src/msw/frame.cpp
src/msw/textctrl.cpp
src/msw/window.cpp

index 5a813e3ddfc59e89856ed87aeaa8cd499c41c26f..f47c9afc4199667d95682efe0342a2d6ee58028b 100644 (file)
@@ -79,15 +79,15 @@ public:
     void OnFocus(wxFocusEvent& event);
 
         // called by wxWindow whenever it gets focus
-    void SetLastFocus(long focus) { m_lastFocus = focus; }
-    long GetLastFocus() const { return m_lastFocus; }
+    void SetLastFocus(wxWindow *win) { m_winLastFocused = win; }
+    wxWindow *GetLastFocus() const { return m_winLastFocused; }
 
 protected:
     // common part of all ctors
     void Init();
 
     // the child which had the focus last time this panel was activated
-    long m_lastFocus;
+    wxWindow *m_winLastFocused;
 
     // a default button or NULL
     wxButton *m_btnDefault;
index 87709ad66a4b3dcc167a3a3f55fcca2783800481..2665e8d0ec4db857086d5373590a1eda156759ad 100644 (file)
@@ -191,6 +191,16 @@ wxWindowBase::~wxWindowBase()
 
     wxASSERT_MSG( GetChildren().GetCount() == 0, _T("children not destroyed") );
 
+    // make sure that there are no dangling pointers left pointing to us
+    wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
+    if ( panel )
+    {
+        if ( panel->GetLastFocus() == this )
+        {
+            panel->SetLastFocus((wxWindow *)NULL);
+        }
+    }
+
 #if wxUSE_CARET
     if ( m_caret )
         delete m_caret;
index 9ae28654823f284c81c5084134f861def2cb0946..9f719780e4636cc0c54e4fea9e7c25a38a7a38a8 100644 (file)
@@ -42,7 +42,7 @@ END_EVENT_TABLE()
 
 void wxPanel::Init()
 {
-    m_lastFocus = 0;
+    m_winLastFocused = (wxWindow *)NULL;
     m_btnDefault = (wxButton *)NULL;
 }
 
@@ -144,11 +144,13 @@ void wxPanel::OnNavigationKey( wxNavigationKeyEvent& event )
 
 void wxPanel::OnFocus(wxFocusEvent& event)
 {
-    if (m_lastFocus != 0)
+    if ( m_winLastFocused )
     {
-        wxWindow* child = FindWindow(m_lastFocus);
-        if (child)
-            child->SetFocus();
+        // it might happen that the window got reparented...
+        if ( m_winLastFocused->GetParent() != this )
+            m_winLastFocused = (wxWindow *)NULL;
+        else
+            m_winLastFocused->SetFocus();
     }
     else
         event.Skip();
index 48d39d7495fec4abaac98db6b01904a94277195b..4cba2dd81f22687da8cccfe710ec3c5075b9a2d0 100644 (file)
@@ -86,9 +86,6 @@ bool wxFrame::Create(wxWindow *parent,
     m_hwndToolTip = 0;
 #endif
 
-  if (!parent)
-    wxTopLevelWindows.Append(this);
-
   SetName(name);
   m_windowStyle = style;
   m_frameMenuBar = NULL;
@@ -119,6 +116,9 @@ bool wxFrame::Create(wxWindow *parent,
   if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
     parent = NULL;
 
+  if (!parent)
+    wxTopLevelWindows.Append(this);
+
   MSWCreate(m_windowId, parent, wxFrameClassName, this, title,
             x, y, width, height, style);
 
@@ -609,17 +609,29 @@ void wxFrame::OnSize(wxSizeEvent& event)
 // subwindow found.
 void wxFrame::OnActivate(wxActivateEvent& event)
 {
-  for(wxNode *node = GetChildren().First(); node; node = node->Next())
-  {
-    // Find a child that's a subwindow, but not a dialog box.
-    wxWindow *child = (wxWindow *)node->Data();
-    if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
-         !child->IsKindOf(CLASSINFO(wxDialog)))
+    for ( wxWindowList::Node *node = GetChildren().GetFirst();
+          node;
+          node = node->GetNext() )
     {
-      child->SetFocus();
-      return;
+        // FIXME all this is totally bogus - we need to do the same as wxPanel,
+        //       but how to do it without duplicating the code?
+
+        // restore focus
+        wxWindow *child = node->GetData();
+
+        if ( !child->IsTopLevel()
+#if wxUSE_TOOLBAR
+             && !wxDynamicCast(child, wxToolBar)
+#endif // wxUSE_TOOLBAR
+#if wxUSE_STATUSBAR
+             && !wxDynamicCast(child, wxStatusBar)
+#endif // wxUSE_STATUSBAR
+           )
+        {
+            child->SetFocus();
+            return;
+        }
     }
-  }
 }
 
 // The default implementation for the close window event.
index db6f5009c4f665b05b7c55b79c9dda7937862360..d166ede2c26a2dfc75bb101f4b10b21b850efe40 100644 (file)
@@ -1107,13 +1107,13 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
             break;
 
         case WXK_TAB:
-            // only produce navigation event if we don't process TAB ourself or
-            // if it's a Shift-Tab keypress (we assume nobody will ever need
-            // this key combo for himself)
+            // always produce navigation event - even if we process TAB
+            // ourselves the fact that we got here means that the user code
+            // decided to skip processing of this TAB - probably to let it
+            // do its default job.
             //
             // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
             //     handled by Windows
-            if ( event.ShiftDown() || !(m_windowStyle & wxTE_PROCESS_TAB) )
             {
                 wxNavigationKeyEvent eventNav;
                 eventNav.SetDirection(!event.ShiftDown());
index 5a5d8f643488ca57eb25fa858a4efcf5dc8e7a00..a4bfa94f2a6660a1bf725e98757a33352e75b9f7 100644 (file)
@@ -246,6 +246,11 @@ void wxWindow::Init()
     // wxWnd
     m_hMenu = 0;
 
+    m_hWnd = 0;
+
+    // pass WM_GETDLGCODE to DefWindowProc()
+    m_lDlgCode = 0;
+
     m_xThumbSize = 0;
     m_yThumbSize = 0;
     m_backgroundTransparent = FALSE;
@@ -325,11 +330,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
                      DLGC_WANTTAB | DLGC_WANTMESSAGE;
         
     }
-    else
-    {
-        // default behaviour
-        m_lDlgCode = 0;
-    }
 
     MSWCreate(m_windowId, parent, wxCanvasClassName, this, NULL,
               pos.x, pos.y,
@@ -1382,6 +1382,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
         if ( bProcess )
         {
             bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
+            bool bShiftDown = (::GetKeyState(VK_SHIFT) & 0x100) != 0;
 
             // WM_GETDLGCODE: ask the control if it wants the key for itself,
             // don't process it if it's the case (except for Ctrl-Tab/Enter
@@ -1398,13 +1399,16 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
             switch ( msg->wParam )
             {
                 case VK_TAB:
-                    if ( lDlgCode & DLGC_WANTTAB ) {
+                    // assume that nobody wants Shift-TAB for himself - if we
+                    // don't do it there is no easy way for a control to grab
+                    // TABs but still let Shift-TAB work as navugation key
+                    if ( (lDlgCode & DLGC_WANTTAB) && !bShiftDown ) {
                         bProcess = FALSE;
                     }
                     else {
                         // Ctrl-Tab cycles thru notebook pages
                         bWindowChange = bCtrlDown;
-                        bForward = !(::GetKeyState(VK_SHIFT) & 0x100);
+                        bForward = !bShiftDown;
                     }
                     break;
 
@@ -1431,6 +1435,11 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
                             // it
                             return FALSE;
                         }
+                        else if ( lDlgCode & DLGC_BUTTON )
+                        {
+                            // buttons want process Enter themselevs
+                            bProcess = FALSE;
+                        }
                         // else: but if it does not it makes sense to make it
                         //       work like a TAB - and that's what we do.
                         //       Note that Ctrl-Enter always works this way.
@@ -2318,10 +2327,10 @@ bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd))
 #endif // wxUSE_CARET
 
     // panel wants to track the window which was the last to have focus in it
-    wxWindow *parent = GetParent();
-    if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) )
+    wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
+    if ( panel )
     {
-        ((wxPanel *)parent)->SetLastFocus(GetId());
+        panel->SetLastFocus(this);
     }
 
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);