]> git.saurik.com Git - wxWidgets.git/commitdiff
implemented a dirty hack allowing us to keep activation after wxExecute(wxEXEC_SYNC...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 31 Aug 2002 23:43:04 +0000 (23:43 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 31 Aug 2002 23:43:04 +0000 (23:43 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16903 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/utilsexc.cpp

index e550fca890a1276545555fb6dcb8c5a5a7505a1f..e184b84e6d4375b837fa04ce6c61bdf49ac8cfa8 100644 (file)
     #include "wx/utils.h"
     #include "wx/app.h"
     #include "wx/intl.h"
     #include "wx/utils.h"
     #include "wx/app.h"
     #include "wx/intl.h"
+    #include "wx/log.h"
 #endif
 
 #endif
 
-#include "wx/log.h"
-
 #ifdef __WIN32__
     #include "wx/stream.h"
     #include "wx/process.h"
 #ifdef __WIN32__
     #include "wx/stream.h"
     #include "wx/process.h"
@@ -845,12 +844,44 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
         return pi.dwProcessId;
     }
 
         return pi.dwProcessId;
     }
 
-    // waiting until command executed (disable everything while doing it)
+    // disable all app windows while waiting for the child process to finish
 #if wxUSE_GUI
 #if wxUSE_GUI
+
+    /*
+       We use a dirty hack here to disable all application windows (which we
+       must do because otherwise the calls to wxYield() could lead to some very
+       unexpected reentrancies in the users code) but to avoid losing
+       focus/activation entirely when the child process terminates which would
+       happen if we simply disabled everything using wxWindowDisabler. Indeed,
+       remember that Windows will never activate a disabled window and when the
+       last childs window is closed and Windows looks for a window to activate
+       all our windows are still disabled. There is no way to enable them in
+       time because we don't know when the childs windows are going to be
+       closed, so the solution we use here is to keep one special tiny frame
+       enabled all the time. Then when the child terminates it will get
+       activated and when we close it below -- after reenabling all the other
+       windows! -- the previously active window becomes activated again and
+       everything is ok.
+     */
+    wxWindow *winActive;
     {
         wxBusyCursor bc;
 
     {
         wxBusyCursor bc;
 
+        // first disable all existing windows
         wxWindowDisabler wd;
         wxWindowDisabler wd;
+
+        // then create an "invisible" frame: it has minimal size, is positioned
+        // (hopefully) outside the screen and doesn't appear on the taskbar
+        winActive = new wxFrame
+                        (
+                            wxTheApp->GetTopWindow(),
+                            -1,
+                            _T(""),
+                            wxPoint(32600, 32600),
+                            wxSize(1, 1),
+                            wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
+                        );
+        winActive->Show();
 #endif // wxUSE_GUI
 
         // wait until the child process terminates
 #endif // wxUSE_GUI
 
         // wait until the child process terminates
@@ -871,6 +902,11 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
 
 #if wxUSE_GUI
     }
 
 #if wxUSE_GUI
     }
+
+    // finally delete the dummy frame and, as wd has been already destroyed and
+    // the other windows reenabled, the activation is going to return to the
+    // window which had it before
+    winActive->Destroy();
 #endif // wxUSE_GUI
 
     DWORD dwExitCode = data->dwExitCode;
 #endif // wxUSE_GUI
 
     DWORD dwExitCode = data->dwExitCode;