X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0493ba1399a832f9540fc4d2150d2d090b33fb1a..8705ab68e24210788b3c7482f8f9bfe4badd839f:/src/msw/utilsexc.cpp diff --git a/src/msw/utilsexc.cpp b/src/msw/utilsexc.cpp index 3894aaeea7..db4da1ef05 100644 --- a/src/msw/utilsexc.cpp +++ b/src/msw/utilsexc.cpp @@ -32,9 +32,11 @@ #include "wx/utils.h" #include "wx/app.h" #include "wx/intl.h" + #include "wx/log.h" +#if wxUSE_GUI // See 'dirty hack' below. + #include "wx/frame.h" +#endif #endif - -#include "wx/log.h" #ifdef __WIN32__ #include "wx/stream.h" @@ -341,6 +343,10 @@ wxPipeInputStream::~wxPipeInputStream() bool wxPipeInputStream::IsAvailable() const { + // FIXME +#ifdef __WXWINE__ + return FALSE; +#else if ( !IsOpened() ) return FALSE; @@ -374,6 +380,7 @@ bool wxPipeInputStream::IsAvailable() const } return nAvailable != 0; +#endif } size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len) @@ -840,12 +847,44 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler) 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 + + /* + 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; + // first disable all existing windows 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 @@ -866,6 +905,11 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler) #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;