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
// 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);
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();
#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
//
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();
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;
}
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
// 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() )
// 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
// 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
(
#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() )
// showing the dialogs
// ----------------------------------------------------------------------------
-wxWindow *wxDialog::FindSuitableParent() const
-{
- return NULL;
-}
-
bool wxDialog::Show(bool show)
{
if (show && CanDoLayoutAdaptation())