]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/toplevel.cpp
new wxASSERT implementation using wxAssert() helper function
[wxWidgets.git] / src / msw / toplevel.cpp
index 91804dda888d2e5d059b8901e2ebbfd804017b91..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
 // ----------------------------------------------------------------------------
@@ -88,9 +92,9 @@ wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     switch ( message )
     {
         case WM_INITDIALOG:
-            // for this message, returning TRUE tells system to set focus to the
-            // first control in the dialog box
-            return TRUE;
+            // for this message, returning TRUE tells system to set focus to
+            // the first control in the dialog box, but as we set the focus
+            // ourselves, we return FALSE from here as well, so fall through
 
         default:
             // for all the other ones, FALSE means that we didn't process the
@@ -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
@@ -473,6 +479,19 @@ wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
     if ( wxModelessWindows.Find(this) )
         wxModelessWindows.DeleteObject(this);
 
+    // after destroying an owned window, Windows activates the next top level
+    // window in Z order but it may be different from our owner (to reproduce
+    // this simply Alt-TAB to another application and back before closing the
+    // owned frame) whereas we always want to yield activation to our parent
+    if ( HasFlag(wxFRAME_FLOAT_ON_PARENT) )
+    {
+        wxWindow *parent = GetParent();
+        if ( parent )
+        {
+            ::BringWindowToTop(GetHwndOf(parent));
+        }
+    }
+
     // If this is the last top-level window, exit.
     if ( wxTheApp && (wxTopLevelWindows.Number() == 0) )
     {
@@ -728,40 +747,56 @@ bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
 }
 
 // ----------------------------------------------------------------------------
-// wxTopLevelWindowMSW message processing
+// wxTopLevelWindow event handling
 // ----------------------------------------------------------------------------
 
-long wxTopLevelWindowMSW::HandleNcActivate(bool activate)
+// Default activation behaviour - set the focus for the first child
+// subwindow found.
+void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event)
 {
-#if wxUSE_POPUPWIN
-    /*
-       Normally, when another top level (whether it is overlapped or popup)
-       window is shown, it is activated and the parent window (i.e. we) loses
-       the activation. This, however, looks very ugly when the child window is
-       a [custom] combobox which we implement using a popup window as surely
-       opening a combobox shouldn't result in deactivating the parent window.
-
-       So we don't redraw the title bar in this case, even if we still return
-       TRUE to let the change of activation to take place as otherwise the
-       controls inside the popup window wouldn't work properly.
-     */
-    if ( !activate && wxPopupWindow::FindPopupFor(this) )
+    if ( event.GetActive() )
     {
-        return TRUE;
-    }
-#endif // wxUSE_POPUPWIN
+        // restore focus to the child which was last focused
+        wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), m_hWnd);
 
-    return FALSE;
-}
+        wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
+                                            : NULL;
+        if ( !parent )
+        {
+            parent = this;
+        }
 
-long
-wxTopLevelWindowMSW::MSWWindowProc(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam)
-{
-    if ( msg == WM_NCACTIVATE && HandleNcActivate(wParam != 0) )
-    {
-        // we processed WM_NCACTIVATE ourselves
-        return TRUE;
+        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;
+                }
 
-    return wxTopLevelWindowBase::MSWWindowProc(msg, wParam, lParam);
+                break;
+            }
+
+            win = win->GetParent();
+        }
+
+        wxLogTrace(_T("focus"),
+                   _T("wxTLW %08x deactivated, last focused: %08x."),
+                   m_hWnd,
+                   m_winLastFocused ? GetHwndOf(m_winLastFocused)
+                                    : NULL);
+
+        event.Skip();
+    }
 }
+