X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9dfef5ac200277eb1943cde5c1beafa2f392ab88..aad65f130d9cb77d0e9f2b7b580c54712386f77a:/src/msw/toplevel.cpp diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 91804dda88..3a25093115 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -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(); + } } +