Use a single wxTopLevelWindow::m_showCmd flag in wxMSW

This single field replaces m_iconized and m_maximizeOnShow which were
not really independent and will make it simpler to schedule either
maximizing or maximizing the window later, when it can't be done
immediately because the window is hidden, in the following commit.
This commit is contained in:
Vadim Zeitlin
2018-06-22 03:23:31 +02:00
parent f03d655b1a
commit 3518f1a7d8
4 changed files with 67 additions and 54 deletions

View File

@@ -132,9 +132,12 @@ protected:
const wxPoint& pos, const wxPoint& pos,
const wxSize& size); const wxSize& size);
// common part of Iconize(), Maximize() and Restore() // Just a wrapper around MSW ShowWindow().
void DoShowWindow(int nShowCmd); void DoShowWindow(int nShowCmd);
// Return true if the window is iconized at MSW level, ignoring m_showCmd.
bool MSWIsIconized() const;
// override those to return the normal window coordinates even when the // override those to return the normal window coordinates even when the
// window is minimized // window is minimized
virtual void DoGetPosition(int *x, int *y) const wxOVERRIDE; virtual void DoGetPosition(int *x, int *y) const wxOVERRIDE;
@@ -156,13 +159,11 @@ protected:
int& x, int& y, int& x, int& y,
int& w, int& h) const wxOVERRIDE; int& w, int& h) const wxOVERRIDE;
// This field contains the show command to use when showing the window the
// is the window currently iconized? // next time and also indicates whether the window should be considered
bool m_iconized; // being iconized or maximized (which may be different from whether it's
// actually iconized or maximized at MSW level).
// should the frame be maximized when it will be shown? set by Maximize() WXUINT m_showCmd;
// when it is called while the frame is hidden
bool m_maximizeOnShow;
// Data to save/restore when calling ShowFullScreen // Data to save/restore when calling ShowFullScreen
long m_fsStyle; // Passed to ShowFullScreen long m_fsStyle; // Passed to ShowFullScreen

View File

@@ -321,7 +321,7 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar
switch ( wParam ) switch ( wParam )
{ {
case SIZE_MINIMIZED: case SIZE_MINIMIZED:
m_iconized = true; m_showCmd = SW_MINIMIZE;
break; break;
case SIZE_MAXIMIZED: case SIZE_MAXIMIZED:
@@ -331,9 +331,9 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar
if ( m_hGripper ) if ( m_hGripper )
ShowGripper( wParam == SIZE_RESTORED ); ShowGripper( wParam == SIZE_RESTORED );
if ( m_iconized ) if ( m_showCmd == SW_MINIMIZE )
(void)SendIconizeEvent(false); (void)SendIconizeEvent(false);
m_iconized = false; m_showCmd = SW_RESTORE;
break; break;
} }

View File

@@ -261,7 +261,7 @@ void wxFrame::DoGetClientSize(int *x, int *y) const
// generate an artificial resize event // generate an artificial resize event
void wxFrame::SendSizeEvent(int flags) void wxFrame::SendSizeEvent(int flags)
{ {
if ( !m_iconized ) if ( !MSWIsIconized() )
{ {
RECT r = wxGetWindowRect(GetHwnd()); RECT r = wxGetWindowRect(GetHwnd());
@@ -667,7 +667,7 @@ void wxFrame::PositionToolBar()
// on the desktop, but are iconized/restored with it // on the desktop, but are iconized/restored with it
void wxFrame::IconizeChildFrames(bool bIconize) void wxFrame::IconizeChildFrames(bool bIconize)
{ {
m_iconized = bIconize; m_showCmd = bIconize ? SW_MINIMIZE : SW_RESTORE;
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
node; node;
@@ -750,7 +750,7 @@ bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id)
// only do it it if we were iconized before, otherwise resizing the // only do it it if we were iconized before, otherwise resizing the
// parent frame has a curious side effect of bringing it under it's // parent frame has a curious side effect of bringing it under it's
// children // children
if ( !m_iconized ) if ( m_showCmd != SW_MINIMIZE )
break; break;
// restore all child frames too // restore all child frames too
@@ -765,7 +765,7 @@ bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id)
break; break;
} }
if ( !m_iconized ) if ( m_showCmd != SW_MINIMIZE )
{ {
#if wxUSE_STATUSBAR #if wxUSE_STATUSBAR
PositionStatusBar(); PositionStatusBar();

View File

@@ -95,8 +95,7 @@ wxEND_EVENT_TABLE()
void wxTopLevelWindowMSW::Init() void wxTopLevelWindowMSW::Init()
{ {
m_iconized = m_showCmd = SW_SHOWNORMAL;
m_maximizeOnShow = false;
// Data to save/restore when calling ShowFullScreen // Data to save/restore when calling ShowFullScreen
m_fsStyle = 0; m_fsStyle = 0;
@@ -522,14 +521,6 @@ void wxTopLevelWindowMSW::DoShowWindow(int nShowCmd)
{ {
::ShowWindow(GetHwnd(), nShowCmd); ::ShowWindow(GetHwnd(), nShowCmd);
// Hiding the window doesn't change its iconized state.
if ( nShowCmd != SW_HIDE )
{
// Otherwise restoring, maximizing or showing the window normally also
// makes it not iconized and only minimizing it does make it iconized.
m_iconized = nShowCmd == SW_MINIMIZE;
}
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
// Don't leave a tooltip hanging around if TLW is hidden now. // Don't leave a tooltip hanging around if TLW is hidden now.
wxToolTip::UpdateVisibility(); wxToolTip::UpdateVisibility();
@@ -541,7 +532,12 @@ void wxTopLevelWindowMSW::ShowWithoutActivating()
if ( !wxWindowBase::Show(true) ) if ( !wxWindowBase::Show(true) )
return; return;
DoShowWindow(SW_SHOWNA); // We can't show the window in a maximized state without activating it, so
// the sequence of hiding the window, calling Maximize() and this function
// will end up with the window not being maximized -- but this is arguably
// better than activating it and is compatible with the historical
// behaviour of this function.
DoShowWindow(m_showCmd == SW_MINIMIZE ? SW_SHOWMINNOACTIVE : SW_SHOWNA);
} }
bool wxTopLevelWindowMSW::Show(bool show) bool wxTopLevelWindowMSW::Show(bool show)
@@ -553,18 +549,10 @@ bool wxTopLevelWindowMSW::Show(bool show)
int nShowCmd; int nShowCmd;
if ( show ) if ( show )
{ {
if ( m_maximizeOnShow ) // If we need to minimize or maximize the window, do it now.
if ( m_showCmd == SW_MAXIMIZE || m_showCmd == SW_MINIMIZE )
{ {
// show and maximize nShowCmd = m_showCmd;
nShowCmd = SW_MAXIMIZE;
m_maximizeOnShow = false;
}
else if ( m_iconized )
{
// We were iconized while we were hidden, so now we need to show
// the window in iconized state.
nShowCmd = SW_MINIMIZE;
} }
else if ( ::IsIconic(GetHwnd()) ) else if ( ::IsIconic(GetHwnd()) )
{ {
@@ -622,16 +610,19 @@ void wxTopLevelWindowMSW::Raise()
void wxTopLevelWindowMSW::Maximize(bool maximize) void wxTopLevelWindowMSW::Maximize(bool maximize)
{ {
// Update m_showCmd to ensure that the window is maximized when it's shown
// later even if it's currently hidden.
m_showCmd = maximize ? SW_MAXIMIZE : SW_RESTORE;
if ( IsShown() ) if ( IsShown() )
{ {
// just maximize it directly // just maximize it directly
DoShowWindow(maximize ? SW_MAXIMIZE : SW_RESTORE); DoShowWindow(m_showCmd);
} }
else // hidden else // hidden
{ {
// we can't maximize the hidden frame because it shows it as well, // we can't maximize the hidden frame because it shows it as well,
// so just remember that we should do it later in this case // so don't do anything other than updating m_showCmd for now
m_maximizeOnShow = maximize;
#if wxUSE_DEFERRED_SIZING #if wxUSE_DEFERRED_SIZING
// after calling Maximize() the client code expects to get the frame // after calling Maximize() the client code expects to get the frame
@@ -659,45 +650,66 @@ bool wxTopLevelWindowMSW::IsMaximized() const
{ {
return IsAlwaysMaximized() || return IsAlwaysMaximized() ||
(::IsZoomed(GetHwnd()) != 0) || (::IsZoomed(GetHwnd()) != 0) ||
m_maximizeOnShow; m_showCmd == SW_MAXIMIZE;
} }
void wxTopLevelWindowMSW::Iconize(bool iconize) void wxTopLevelWindowMSW::Iconize(bool iconize)
{ {
if ( iconize == m_iconized ) if ( iconize == MSWIsIconized() )
{ {
// Do nothing, in particular don't restore non-iconized windows when // Do nothing, in particular don't restore non-iconized windows when
// Iconize(false) is called as this would wrongly un-maximize them. // Iconize(false) is called as this would wrongly un-maximize them.
return; return;
} }
// Note that we can't change m_showCmd yet as wxFrame WM_SIZE handler uses
// its value to determine whether the frame had been iconized before or not
// and this handler will be called from inside DoShowWindow() below.
const UINT showCmd = iconize ? SW_MINIMIZE : SW_RESTORE;
// We can't actually iconize the window if it's currently hidden, as this
// would also show it unexpectedly.
if ( IsShown() ) if ( IsShown() )
{ {
// change the window state immediately DoShowWindow(showCmd);
DoShowWindow(iconize ? SW_MINIMIZE : SW_RESTORE);
}
else // hidden
{
// iconizing the window shouldn't show it so just update the internal
// state (otherwise it's done by DoShowWindow() itself)
m_iconized = iconize;
} }
// Update the internal flag in any case, so that IsIconized() returns the
// correct value, for example. And if the window is currently hidden, this
// also ensures that the next call to Show() will show it in an iconized
// state instead of showing it normally.
m_showCmd = showCmd;
} }
bool wxTopLevelWindowMSW::IsIconized() const bool wxTopLevelWindowMSW::IsIconized() const
{ {
if ( !IsShown() ) if ( !IsShown() )
return m_iconized; {
// Hidden windows are never actually iconized at MSW level, but can be
// in wx, so use m_showCmd to determine our status.
return m_showCmd == SW_MINIMIZE;
}
// don't use m_iconized, it may be briefly out of sync with the real state // don't use m_showCmd, it may be briefly out of sync with the real state
// as it's only modified when we receive a WM_SIZE and we could be called // as it's only modified when we receive a WM_SIZE and we could be called
// from an event handler from one of the messages we receive before it, // from an event handler from one of the messages we receive before it,
// such as WM_MOVE // such as WM_MOVE
return MSWIsIconized();
}
bool wxTopLevelWindowMSW::MSWIsIconized() const
{
return ::IsIconic(GetHwnd()) != 0; return ::IsIconic(GetHwnd()) != 0;
} }
void wxTopLevelWindowMSW::Restore() void wxTopLevelWindowMSW::Restore()
{ {
// Forget any previous minimized/maximized status.
m_showCmd = SW_SHOW;
// And actually restore the window to its normal state. Note that here,
// unlike in Maximize() and Iconize(), we do it even if the window is
// currently hidden, i.e. Restore() is supposed to show it in this case.
DoShowWindow(SW_RESTORE); DoShowWindow(SW_RESTORE);
} }
@@ -1181,7 +1193,7 @@ void wxTopLevelWindowMSW::DoThaw()
void wxTopLevelWindowMSW::DoSaveLastFocus() void wxTopLevelWindowMSW::DoSaveLastFocus()
{ {
if ( m_iconized ) if ( MSWIsIconized() )
return; return;
// remember the last focused child if it is our child // remember the last focused child if it is our child
@@ -1211,7 +1223,7 @@ void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event)
// We get WM_ACTIVATE before being restored from iconized state, so we // We get WM_ACTIVATE before being restored from iconized state, so we
// can be still iconized here. In this case, avoid restoring the focus // can be still iconized here. In this case, avoid restoring the focus
// as it doesn't work anyhow and we will do when we're really restored. // as it doesn't work anyhow and we will do when we're really restored.
if ( m_iconized ) if ( MSWIsIconized() )
{ {
event.Skip(); event.Skip();
return; return;