]> git.saurik.com Git - wxWidgets.git/commitdiff
added wxWS_EX_TRANSIENT, added code for handling it and fixed wxLogGeneric
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 30 Nov 2001 23:40:12 +0000 (23:40 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 30 Nov 2001 23:40:12 +0000 (23:40 +0000)
to avoid crashes related to creating the log dialog as child of a window which
is destroyed before it is

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12781 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/latex/wx/window.tex
include/wx/defs.h
src/generic/logg.cpp
src/generic/progdlgg.cpp
src/gtk/dialog.cpp
src/gtk1/dialog.cpp
src/msw/toplevel.cpp

index 77e76e7270af651c212eefb0a1580257c2c70bdb..106ff9e65d65ca56730d4de729c14a6360f8b444 100644 (file)
@@ -2068,6 +2068,10 @@ for them is found. Using this style allows to prevent them from being
 propagated beyond this window. Notice that wxDialog has this style on by
 default for the reasons explained in the 
 \helpref{event processing overview}{eventprocessing}.}
+\twocolitem{\windowstyle{wxWS\_EX\_TRANSIENT}}{This can be used to prevent a
+window from being used as an implicit parent for the dialogs which were
+created without a parent. It is useful for the windows which can disappear at
+any moment as creating childs of such windows results in fatal problems.}
 \end{twocollist}
 
 \membersection{wxWindow::SetFocus}\label{wxwindowsetfocus}
index 91b788c8f856fc2f02885df5e74b41f2ea32ce5e..39578aaa318fc16d7b192349bcd93ac5d5cdfd7d 100644 (file)
@@ -784,6 +784,12 @@ enum wxBorder
 // flag on by default.
 #define wxWS_EX_BLOCK_EVENTS            0x00000002
 
+// don't use this window as an implicit parent for the other windows: this must
+// be used with transient windows as otherwise there is the risk of creating a
+// dialog/frame with this window as a parent which would lead to a crash if the
+// parent is destroyed before the child
+#define wxWS_EX_TRANSIENT               0x00000004
+
 /*
  * wxFrame/wxDialog style flags
  */
index a0ff4d36721712bffb44a1b0687b43f3566f8ced..155628d82785075f12a36f19c5ae12b678b96928 100644 (file)
@@ -245,9 +245,6 @@ void wxLogGui::Flush()
     wxString title;
     title.Printf(titleFormat, appName.c_str());
 
-    // this is the best we can do here
-    wxWindow *parent = wxTheApp->GetTopWindow();
-
     size_t nMsgCount = m_aMessages.Count();
 
     // avoid showing other log dialogs until we're done with the dialog we're
@@ -263,7 +260,7 @@ void wxLogGui::Flush()
     {
 #if wxUSE_LOG_DIALOG
 
-        wxLogDialog dlg(parent,
+        wxLogDialog dlg(NULL,
                         m_aMessages, m_aSeverity, m_aTimes,
                         title, style);
 
@@ -295,7 +292,7 @@ void wxLogGui::Flush()
     // situation without it
     if ( !!str )
     {
-        wxMessageBox(str, title, wxOK | style, parent);
+        wxMessageBox(str, title, wxOK | style);
 
         // no undisplayed messages whatsoever
         Clear();
index 94109c5660157d515ff71887c3ae7a598f314cf9..33a8d648fcdda97cd56edf3e4f28a895a1b7ad13 100644 (file)
@@ -89,6 +89,9 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
                                    int style)
                 : wxDialog(parent, -1, title)
 {
+    // we may disappear at any moment, let the others know about it
+    SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
+
     m_windowStyle |= style;
 
     bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
index e948cddd10abb7b784a68c8324a17df2264a2566..68a991a37175a6f41c79feb1dc5e053114eb683f 100644 (file)
@@ -198,7 +198,10 @@ int wxDialog::ShowModal()
     if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
     {
         wxWindow *parent = wxTheApp->GetTopWindow();
-        if ( parent && parent != this && parent->IsBeingDeleted() )
+        if ( parent &&
+                parent != this &&
+                    parent->IsBeingDeleted() &&
+                        !(parent->GetExtraStyle() & wxWS_EX_TRANSIENT) )
         {
             m_parent = parent;
             gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(parent->m_widget) );
index e948cddd10abb7b784a68c8324a17df2264a2566..68a991a37175a6f41c79feb1dc5e053114eb683f 100644 (file)
@@ -198,7 +198,10 @@ int wxDialog::ShowModal()
     if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
     {
         wxWindow *parent = wxTheApp->GetTopWindow();
-        if ( parent && parent != this && parent->IsBeingDeleted() )
+        if ( parent &&
+                parent != this &&
+                    parent->IsBeingDeleted() &&
+                        !(parent->GetExtraStyle() & wxWS_EX_TRANSIENT) )
         {
             m_parent = parent;
             gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(parent->m_widget) );
index 4482e103d9e1ec1feb45945cb2f5e253ecc0d43f..a7b917f9f112a95a58380147ff72a91930bb289f 100644 (file)
@@ -196,11 +196,18 @@ bool wxTopLevelWindowMSW::CreateDialog(const wxChar *dlgTemplate,
     {
         parent = wxTheApp->GetTopWindow();
 
-        // but don't use the window which is currently hidden as then the
-        // dialog would be hidden as well
-        if ( parent && !parent->IsShown() )
+        if ( parent )
         {
-            parent = NULL;
+            // 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;
+            }
         }
     }