remove wxMSW-specific FindSuitableParent() and use GetParentForModalDialog() everywhere; extend it with additional checks and remove redundant ones elsewhere
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60559 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
889e742216
commit
8bda0ec6a3
@ -91,7 +91,7 @@ public:
|
||||
int GetEscapeId() const { return m_escapeId; }
|
||||
|
||||
// Returns the parent to use for modal dialogs if the user did not specify it
|
||||
// explicitly
|
||||
// explicitly. If parent argument is NULL, use GetParent() by default.
|
||||
wxWindow *GetParentForModalDialog(wxWindow *parent = NULL) const;
|
||||
|
||||
#if wxUSE_STATTEXT // && wxUSE_TEXTCTRL
|
||||
@ -211,6 +211,10 @@ private:
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
// helper of GetParentForModalDialog(): returns the passed in window if it
|
||||
// can be used as our parent or NULL if it can't
|
||||
wxWindow *CheckIfCanBeUsedAsParent(wxWindow *parent) const;
|
||||
|
||||
// handle Esc key presses
|
||||
void OnCharHook(wxKeyEvent& event);
|
||||
|
||||
|
@ -108,12 +108,6 @@ public:
|
||||
WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
|
||||
|
||||
protected:
|
||||
// find the window to use as parent for this dialog if none has been
|
||||
// specified explicitly by the user
|
||||
//
|
||||
// may return NULL
|
||||
wxWindow *FindSuitableParent() const;
|
||||
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
|
@ -95,14 +95,6 @@ public:
|
||||
#endif // WXWIN_COMPATIBILITY_2_6
|
||||
|
||||
protected:
|
||||
//
|
||||
// find the window to use as parent for this dialog if none has been
|
||||
// specified explicitly by the user
|
||||
//
|
||||
// may return NULL
|
||||
//
|
||||
wxWindow *FindSuitableParent() const;
|
||||
|
||||
//
|
||||
// Common part of all ctors
|
||||
//
|
||||
|
@ -64,12 +64,6 @@ public:
|
||||
virtual void Raise();
|
||||
|
||||
protected:
|
||||
// find the window to use as parent for this dialog if none has been
|
||||
// specified explicitly by the user
|
||||
//
|
||||
// may return NULL
|
||||
wxWindow *FindSuitableParent() const;
|
||||
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
|
@ -78,32 +78,63 @@ void wxDialogBase::Init()
|
||||
SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
|
||||
}
|
||||
|
||||
// helper of GetParentForModalDialog()
|
||||
static bool CanBeUsedAsParent(wxWindow *parent)
|
||||
wxWindow *wxDialogBase::CheckIfCanBeUsedAsParent(wxWindow *parent) const
|
||||
{
|
||||
extern WXDLLIMPEXP_DATA_CORE(wxList) wxPendingDelete;
|
||||
|
||||
return !parent->HasExtraStyle(wxWS_EX_TRANSIENT) &&
|
||||
parent->IsShownOnScreen() &&
|
||||
!wxPendingDelete.Member(parent) &&
|
||||
!parent->IsBeingDeleted();
|
||||
if ( wxPendingDelete.Member(parent) || parent->IsBeingDeleted() )
|
||||
{
|
||||
// this window is being deleted and we shouldn't create any children
|
||||
// under it
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( parent->HasExtraStyle(wxWS_EX_TRANSIENT) )
|
||||
{
|
||||
// this window is not being deleted yet but it's going to disappear
|
||||
// soon so still don't parent this window under it
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !parent->IsShownOnScreen() )
|
||||
{
|
||||
// using hidden parent won't work correctly neither
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( parent == this )
|
||||
{
|
||||
// not sure if this can really happen but it doesn't hurt to guard
|
||||
// against this clearly invalid situation
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
wxWindow *wxDialogBase::GetParentForModalDialog(wxWindow *parent) const
|
||||
{
|
||||
// creating a parent-less modal dialog will result (under e.g. wxGTK2)
|
||||
// in an unfocused dialog, so try to find a valid parent for it:
|
||||
// in an unfocused dialog, so try to find a valid parent for it unless we
|
||||
// were explicitly asked not to
|
||||
if ( HasFlag(wxDIALOG_NO_PARENT) )
|
||||
return NULL;
|
||||
|
||||
// by default, use the parent specified in the ctor
|
||||
if ( !parent )
|
||||
parent = GetParent();
|
||||
|
||||
// first try the given parent
|
||||
if ( parent )
|
||||
parent = wxGetTopLevelParent(parent);
|
||||
parent = CheckIfCanBeUsedAsParent(wxGetTopLevelParent(parent));
|
||||
|
||||
if ( !parent || !CanBeUsedAsParent(parent) )
|
||||
parent = wxTheApp->GetTopWindow();
|
||||
// then the currently active window
|
||||
if ( !parent )
|
||||
parent = CheckIfCanBeUsedAsParent(wxGetActiveWindow());
|
||||
|
||||
if ( parent && !CanBeUsedAsParent(parent) )
|
||||
{
|
||||
// can't use this one, it's going to disappear
|
||||
parent = NULL;
|
||||
}
|
||||
// and finally the application main window
|
||||
if ( !parent )
|
||||
parent = CheckIfCanBeUsedAsParent(wxTheApp->GetTopWindow());
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
@ -111,16 +111,11 @@ int wxDialog::ShowModal()
|
||||
if ( win )
|
||||
win->GTKReleaseMouseAndNotify();
|
||||
|
||||
// use the apps top level window as parent if none given unless explicitly
|
||||
// forbidden
|
||||
if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
|
||||
wxWindow * const parent = GetParentForModalDialog();
|
||||
if ( parent )
|
||||
{
|
||||
wxWindow * const parent = GetParentForModalDialog();
|
||||
if ( parent && parent != this )
|
||||
{
|
||||
gtk_window_set_transient_for( GTK_WINDOW(m_widget),
|
||||
GTK_WINDOW(parent->m_widget) );
|
||||
}
|
||||
gtk_window_set_transient_for( GTK_WINDOW(m_widget),
|
||||
GTK_WINDOW(parent->m_widget) );
|
||||
}
|
||||
|
||||
wxBusyCursorSuspender cs; // temporarily suppress the busy cursor
|
||||
|
@ -208,28 +208,6 @@ wxDialog::~wxDialog()
|
||||
// showing the dialogs
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxWindow *wxDialog::FindSuitableParent() const
|
||||
{
|
||||
// first try to use the currently active window
|
||||
HWND hwndFg = ::GetForegroundWindow();
|
||||
wxWindow *parent = hwndFg ? wxFindWinFromHandle((WXHWND)hwndFg)
|
||||
: NULL;
|
||||
if ( !parent )
|
||||
{
|
||||
// next try the main app window
|
||||
parent = wxTheApp->GetTopWindow();
|
||||
}
|
||||
|
||||
// finally, check if the parent we found is really suitable
|
||||
if ( !parent || parent == (wxWindow *)this || !parent->IsShown() )
|
||||
{
|
||||
// don't use this one
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool wxDialog::Show(bool show)
|
||||
{
|
||||
if ( show == IsShown() )
|
||||
|
@ -442,7 +442,7 @@ int wxMessageDialog::ShowModal()
|
||||
|
||||
// use the top level window as parent if none specified
|
||||
if ( !m_parent )
|
||||
m_parent = FindSuitableParent();
|
||||
m_parent = GetParentForModalDialog();
|
||||
HWND hWnd = m_parent ? GetHwndOf(m_parent) : NULL;
|
||||
|
||||
// translate wx style in MSW
|
||||
|
@ -373,29 +373,9 @@ bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
|
||||
// no dialogs support under MicroWin yet
|
||||
return CreateFrame(title, pos, size);
|
||||
#else // !__WXMICROWIN__
|
||||
wxWindow *parent = GetParent();
|
||||
|
||||
// for the dialogs without wxDIALOG_NO_PARENT style, use the top level
|
||||
// app window as parent - this avoids creating modal dialogs without
|
||||
// parent
|
||||
if ( !parent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
|
||||
{
|
||||
parent = wxTheApp->GetTopWindow();
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
// don't use transient windows as parents, this is dangerous as it
|
||||
// can lead to a crash if the parent is destroyed before the child
|
||||
//
|
||||
// also don't use the window which is currently hidden as then the
|
||||
// dialog would be hidden as well
|
||||
if ( (parent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
|
||||
!parent->IsShown() )
|
||||
{
|
||||
parent = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
// static cast is valid as we're only ever called for dialogs
|
||||
wxWindow * const
|
||||
parent = static_cast<wxDialog *>(this)->GetParentForModalDialog();
|
||||
|
||||
m_hWnd = (WXHWND)::CreateDialogIndirect
|
||||
(
|
||||
|
@ -166,28 +166,6 @@ bool wxDialog::IsModalShowing() const
|
||||
|
||||
#endif // WXWIN_COMPATIBILITY_2_6
|
||||
|
||||
wxWindow *wxDialog::FindSuitableParent() const
|
||||
{
|
||||
// first try to use the currently active window
|
||||
HWND hwndFg = ::WinQueryActiveWindow(HWND_DESKTOP);
|
||||
wxWindow *parent = hwndFg ? wxFindWinFromHandle((WXHWND)hwndFg)
|
||||
: NULL;
|
||||
if ( !parent )
|
||||
{
|
||||
// next try the main app window
|
||||
parent = wxTheApp->GetTopWindow();
|
||||
}
|
||||
|
||||
// finally, check if the parent we found is really suitable
|
||||
if ( !parent || parent == (wxWindow *)this || !parent->IsShown() )
|
||||
{
|
||||
// don't use this one
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool wxDialog::Show( bool bShow )
|
||||
{
|
||||
if ( bShow == IsShown() )
|
||||
|
@ -161,11 +161,6 @@ wxDialog::~wxDialog()
|
||||
// showing the dialogs
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxWindow *wxDialog::FindSuitableParent() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool wxDialog::Show(bool show)
|
||||
{
|
||||
if (show && CanDoLayoutAdaptation())
|
||||
|
Loading…
Reference in New Issue
Block a user