]> git.saurik.com Git - wxWidgets.git/commitdiff
moved OnActivate() logic from wxFrame to wxDialog -- this fixes infinite loop when...
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 13 Jun 2002 00:04:22 +0000 (00:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 13 Jun 2002 00:04:22 +0000 (00:04 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15816 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/frame.h
include/wx/msw/toplevel.h
src/common/wincmn.cpp
src/msw/frame.cpp
src/msw/toplevel.cpp
src/msw/window.cpp

index b3f81e6c796b9bd30803d8826fa37bea1a523e59..4b4b657d2f01ad6d01eeadf9e00b965af27b7719 100644 (file)
@@ -52,7 +52,6 @@ public:
     // -------------------------------
 
     // event handlers
-    void OnActivate(wxActivateEvent& event);
     void OnSysColourChanged(wxSysColourChangedEvent& event);
 
     // Toolbar
@@ -103,10 +102,6 @@ public:
     // current size - this has an effect of refreshing the window layout
     void SendSizeEvent();
 
-    // called by wxWindow whenever it gets focus
-    void SetLastFocus(wxWindow *win) { m_winLastFocused = win; }
-    wxWindow *GetLastFocus() const { return m_winLastFocused; }
-
 protected:
     // common part of all ctors
     void Init();
@@ -142,14 +137,10 @@ protected:
     static bool           m_useNativeStatusBar;
 #endif // wxUSE_STATUSBAR
 
-    // the last focused child: we restore focus to it on activation
-    wxWindow             *m_winLastFocused;
-
     // Data to save/restore when calling ShowFullScreen
     int                   m_fsStatusBarFields; // 0 for no status bar
     int                   m_fsStatusBarHeight;
     int                   m_fsToolBarHeight;
-//    WXHMENU               m_fsMenu;
 
 private:
 #if wxUSE_TOOLTIPS
index 6f14456c2ee2e4efc1f089b9a602ada9572794f4..d09a48ce0a30ae392d674773cca06010fbb7ac04 100644 (file)
@@ -70,6 +70,13 @@ public:
     // implementation from now on
     // --------------------------
 
+    // event handlers
+    void OnActivate(wxActivateEvent& event);
+
+    // called by wxWindow whenever it gets focus
+    void SetLastFocus(wxWindow *win) { m_winLastFocused = win; }
+    wxWindow *GetLastFocus() const { return m_winLastFocused; }
+
 protected:
     // common part of all ctors
     void Init();
@@ -89,10 +96,6 @@ protected:
     // common part of Iconize(), Maximize() and Restore()
     void DoShowWindow(int nShowCmd);
 
-    // prevent the window from being deactivated sometimes (see comments in the
-    // code)
-    long HandleNcActivate(bool activate);
-
     // translate wxWindows flags to Windows ones
     virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
 
@@ -113,9 +116,14 @@ protected:
     bool                  m_fsIsMaximized;
     bool                  m_fsIsShowing;
 
+    // the last focused child: we restore focus to it on activation
+    wxWindow             *m_winLastFocused;
+
     // the hidden parent window for the frames which shouldn't appear in the
     // taskbar
     static wxWindow *ms_hiddenParent;
+
+    DECLARE_EVENT_TABLE()
 };
 
 // list of all frames and modeless dialogs
index faa3837b1c3d033ca61507ccf74fd9ab9264648c..1d70eebd623700259a1b7957126e362d4f45072b 100644 (file)
@@ -364,6 +364,17 @@ void wxWindowBase::Centre(int direction)
             }
         }
 
+        // we shouldn't center the dialog on the iconized window: under
+        // Windows, for example, this places it completely off the screen
+        if ( parent )
+        {
+            wxTopLevelWindow *winTop = wxDynamicCast(parent, wxTopLevelWindow);
+            if ( winTop && winTop->IsIconized() )
+            {
+                parent = NULL;
+            }
+        }
+
         // did we find the parent?
         if ( !parent )
         {
index 98c8c7eacdcd5523ef33754120cad4d4fa68711e..10896a17f6d81ed6b7db9a85475bd348303172bb 100644 (file)
@@ -72,7 +72,6 @@
 // ----------------------------------------------------------------------------
 
 BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
-    EVT_ACTIVATE(wxFrame::OnActivate)
     EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
 END_EVENT_TABLE()
 
@@ -108,11 +107,8 @@ void wxFrame::Init()
     m_fsStatusBarFields = 0;
     m_fsStatusBarHeight = 0;
     m_fsToolBarHeight = 0;
-//  m_fsMenu = 0;
 
     m_wasMinimized = FALSE;
-
-    m_winLastFocused = (wxWindow *)NULL;
 }
 
 bool wxFrame::Create(wxWindow *parent,
@@ -324,7 +320,7 @@ void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
 // Pass TRUE to show full screen, FALSE to restore.
 bool wxFrame::ShowFullScreen(bool show, long style)
 {
-    if ( IsFullScreen() == show ) 
+    if ( IsFullScreen() == show )
         return FALSE;
 
     if (show)
@@ -395,58 +391,8 @@ bool wxFrame::ShowFullScreen(bool show, long style)
             SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
 #endif
     }
-    
-    return wxFrameBase::ShowFullScreen(show, style);
-}
-
-// Default activation behaviour - set the focus for the first child
-// subwindow found.
-void wxFrame::OnActivate(wxActivateEvent& event)
-{
-    if ( event.GetActive() )
-    {
-        // restore focus to the child which was last focused
-        wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd);
-
-        wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
-                                            : NULL;
-        if ( !parent )
-        {
-            parent = this;
-        }
-
-        wxSetFocusToChild(parent, &m_winLastFocused);
-    }
-    else // deactivating
-    {
-        // remember the last focused child if it is our child
-        m_winLastFocused = FindFocus();
 
-        // so we NULL it out if it's a child from some other frame
-        wxWindow *win = m_winLastFocused;
-        while ( win )
-        {
-            if ( win->IsTopLevel() )
-            {
-                if ( win != this )
-                {
-                    m_winLastFocused = NULL;
-                }
-
-                break;
-            }
-
-            win = win->GetParent();
-        }
-
-        wxLogTrace(_T("focus"),
-                   _T("wxFrame %08x deactivated, last focused: %08x."),
-                   m_hWnd,
-                   m_winLastFocused ? GetHwndOf(m_winLastFocused)
-                                    : NULL);
-
-        event.Skip();
-    }
+    return wxFrameBase::ShowFullScreen(show, style);
 }
 
 // ----------------------------------------------------------------------------
index 842a8a587ba07ceba617156dcaf2d2a8fc1853ad..3a25093115d0036f6149120023f8aa03ebab7cd4 100644 (file)
@@ -77,6 +77,10 @@ wxWindow *wxTopLevelWindowMSW::ms_hiddenParent = NULL;
 // wxTopLevelWindowMSW implementation
 // ============================================================================
 
+BEGIN_EVENT_TABLE(wxTopLevelWindowMSW, wxTopLevelWindowBase)
+    EVT_ACTIVATE(wxTopLevelWindowMSW::OnActivate)
+END_EVENT_TABLE()
+
 // ----------------------------------------------------------------------------
 // wxDialog helpers
 // ----------------------------------------------------------------------------
@@ -116,6 +120,8 @@ void wxTopLevelWindowMSW::Init()
     m_fsOldWindowStyle = 0;
     m_fsIsMaximized = FALSE;
     m_fsIsShowing = FALSE;
+
+    m_winLastFocused = (wxWindow *)NULL;
 }
 
 WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
@@ -740,3 +746,57 @@ bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
     return TRUE;
 }
 
+// ----------------------------------------------------------------------------
+// wxTopLevelWindow event handling
+// ----------------------------------------------------------------------------
+
+// Default activation behaviour - set the focus for the first child
+// subwindow found.
+void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event)
+{
+    if ( event.GetActive() )
+    {
+        // restore focus to the child which was last focused
+        wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), m_hWnd);
+
+        wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
+                                            : NULL;
+        if ( !parent )
+        {
+            parent = this;
+        }
+
+        wxSetFocusToChild(parent, &m_winLastFocused);
+    }
+    else // deactivating
+    {
+        // remember the last focused child if it is our child
+        m_winLastFocused = FindFocus();
+
+        // so we NULL it out if it's a child from some other frame
+        wxWindow *win = m_winLastFocused;
+        while ( win )
+        {
+            if ( win->IsTopLevel() )
+            {
+                if ( win != this )
+                {
+                    m_winLastFocused = NULL;
+                }
+
+                break;
+            }
+
+            win = win->GetParent();
+        }
+
+        wxLogTrace(_T("focus"),
+                   _T("wxTLW %08x deactivated, last focused: %08x."),
+                   m_hWnd,
+                   m_winLastFocused ? GetHwndOf(m_winLastFocused)
+                                    : NULL);
+
+        event.Skip();
+    }
+}
+
index ff531d4eaa2bd075eae7b599fd1f889cc96db270..af673944c34a34caa6e343b785637b6bd612b54c 100644 (file)
@@ -348,12 +348,12 @@ wxWindowMSW::~wxWindowMSW()
     // VS: make sure there's no wxFrame with last focus set to us:
     for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
     {
-        wxFrame *frame = wxDynamicCast(win, wxFrame);
+        wxTopLevelWindow *frame = wxDynamicCast(win, wxTopLevelWindow);
         if ( frame )
         {
             if ( frame->GetLastFocus() == this )
             {
-                frame->SetLastFocus((wxWindow*)NULL);
+                frame->SetLastFocus(NULL);
             }
             break;
         }
@@ -2083,15 +2083,27 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
             // ::IsDialogMessage() can enter in an infinite loop when
             // WS_EX_CONTROLPARENT is specified and the currently focused
             // window is disabled or hidden, so don't call it in this case
+            bool canSafelyCallIsDlgMsg = TRUE;
+
             HWND hwndFocus = ::GetFocus();
-            if ( !hwndFocus ||
-                  ::IsWindowEnabled(hwndFocus) && ::IsWindowVisible(hwndFocus) )
+            while ( hwndFocus )
             {
-                if ( ::IsDialogMessage(GetHwnd(), msg) )
+                if ( !::IsWindowEnabled(hwndFocus) ||
+                        !::IsWindowVisible(hwndFocus) )
                 {
-                    // IsDialogMessage() did something...
-                    return TRUE;
+                    // it would enter an infinite loop if we do this!
+                    canSafelyCallIsDlgMsg = FALSE;
+
+                    break;
                 }
+
+                hwndFocus = ::GetParent(hwndFocus);
+            }
+
+            if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) )
+            {
+                // IsDialogMessage() did something...
+                return TRUE;
             }
         }
     }