]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/utilsexc.cpp
1. wxWindowDisabler modified to bring parent window back to top under MSW
[wxWidgets.git] / src / msw / utilsexc.cpp
index 411eaeaf44c33cfcc8d4ee1229b8b1561502fffb..453b7efc5d82151bde76325650bafc3240c0027d 100644 (file)
@@ -158,7 +158,7 @@ protected:
 wxPipeInputStream::wxPipeInputStream(HANDLE hInput)
 {
     m_hInput = hInput;
-}   
+}
 
 wxPipeInputStream::~wxPipeInputStream()
 {
@@ -186,7 +186,7 @@ size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len)
 wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput)
 {
     m_hOutput = hOutput;
-}   
+}
 
 wxPipeOutputStream::~wxPipeOutputStream()
 {
@@ -401,43 +401,52 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
 
     return result;
 #else // 1
-                     
-    HANDLE h_readPipe[2];
-    HANDLE h_writePipe[2];
-    HANDLE h_oldreadPipe;
-    HANDLE h_oldwritePipe;
-    BOOL inheritHandles;
-
-    // ------------------------------------
-    // Pipe handling
-    // We are in the case of opening a pipe
-    inheritHandles = FALSE;
-    if (handler && handler->NeedPipe()) {
+
+    HANDLE hpipeRead[2];
+    HANDLE hpipeWrite[2];
+    HANDLE hStdIn = INVALID_HANDLE_VALUE;
+    HANDLE hStdOut = INVALID_HANDLE_VALUE;
+
+    // we need to inherit handles in the child process if we want to redirect
+    // its IO
+    BOOL inheritHandles = FALSE;
+
+    // open the pipes to which child process IO will be redirected if needed
+    if ( handler && handler->IsRedirected() )
+    {
         SECURITY_ATTRIBUTES security;
 
         security.nLength              = sizeof(security);
         security.lpSecurityDescriptor = NULL;
         security.bInheritHandle       = TRUE;
 
-        if (! ::CreatePipe(&h_readPipe[0], &h_readPipe[1], &security, 0) ) {
-            wxLogSysError(_T("Can't create the inter-process read pipe"));
+        if ( !::CreatePipe(&hpipeRead[0], &hpipeRead[1], &security, 0) )
+        {
+            wxLogSysError(_("Can't create the inter-process read pipe"));
 
             return 0;
         }
 
-        if (! ::CreatePipe(&h_writePipe[0], &h_writePipe[1], &security, 0) ) {
-            wxLogSysError(_T("Can't create the inter-process read pipe"));
+        if ( !::CreatePipe(&hpipeWrite[0], &hpipeWrite[1], &security, 0) )
+        {
+            ::CloseHandle(hpipeRead[0]);
+            ::CloseHandle(hpipeRead[1]);
+
+            wxLogSysError(_("Can't create the inter-process write pipe"));
 
             return 0;
         }
 
         // We need to save the old stdio handles to restore them after the call
         // to CreateProcess
-        h_oldreadPipe  = GetStdHandle(STD_INPUT_HANDLE);
-        h_oldwritePipe = GetStdHandle(STD_OUTPUT_HANDLE);
+        hStdIn  = ::GetStdHandle(STD_INPUT_HANDLE);
+        hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
 
-        SetStdHandle(STD_INPUT_HANDLE, h_readPipe[0]);
-        SetStdHandle(STD_OUTPUT_HANDLE, h_writePipe[1]);
+        if ( !::SetStdHandle(STD_INPUT_HANDLE, hpipeRead[0]) ||
+             !::SetStdHandle(STD_OUTPUT_HANDLE, hpipeWrite[1]) )
+        {
+            wxLogDebug(_T("Failed to change stdin/out handles"));
+        }
 
         inheritHandles = TRUE;
     }
@@ -464,29 +473,37 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
                          &pi         // process info
                         ) == 0 )
     {
-        if (inheritHandles) {
-            ::CloseHandle(h_writePipe[0]);
-            ::CloseHandle(h_writePipe[1]);
-            ::CloseHandle(h_readPipe[0]);
-            ::CloseHandle(h_readPipe[1]);
+        if ( inheritHandles )
+        {
+            ::CloseHandle(hpipeWrite[0]);
+            ::CloseHandle(hpipeWrite[1]);
+            ::CloseHandle(hpipeRead[0]);
+            ::CloseHandle(hpipeRead[1]);
         }
+
         wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
 
         return 0;
     }
 
     // Restore the old stdio handles
-    if (inheritHandles) {
-        SetStdHandle(STD_INPUT_HANDLE, h_oldreadPipe);
-        SetStdHandle(STD_OUTPUT_HANDLE, h_oldwritePipe);
+    if ( inheritHandles )
+    {
+        if ( !::SetStdHandle(STD_INPUT_HANDLE, hStdIn) ||
+             !::SetStdHandle(STD_OUTPUT_HANDLE, hStdOut) )
+        {
+            wxLogDebug(_T("Failed to restore old stdin/out handles"));
+        }
+
+        // they're still opened in child process
+        ::CloseHandle(hpipeWrite[1]);
+        ::CloseHandle(hpipeRead[0]);
 
-        ::CloseHandle(h_writePipe[1]);
-        ::CloseHandle(h_readPipe[0]);
         // We can now initialize the wxStreams
-        wxInputStream *processOutput = new wxPipeInputStream(h_writePipe[0]);
-        wxOutputStream *processInput = new wxPipeOutputStream(h_readPipe[1]);
+        wxInputStream *inStream = new wxPipeInputStream(hpipeWrite[0]);
+        wxOutputStream *outStream = new wxPipeOutputStream(hpipeRead[1]);
 
-        handler->SetPipeStreams(processOutput, processInput);
+        handler->SetPipeStreams(inStream, outStream);
     }
 
     // register the class for the hidden window used for the notifications
@@ -522,8 +539,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
     data->state       = sync;
     if ( sync )
     {
-        wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") );
-
+        // handler may be !NULL for capturing program output, but we don't use
+        // it wxExecuteData struct in this case
         data->handler = NULL;
     }
     else
@@ -589,16 +606,17 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
 
     // waiting until command executed (disable everything while doing it)
 #if wxUSE_GUI
-    wxBeginBusyCursor();
-    wxEnableTopLevelWindows(FALSE);
+    {
+        wxBusyCursor bc;
+
+        wxWindowDisabler wd;
 #endif // wxUSE_GUI
 
     while ( data->state )
         wxYield();
 
 #if wxUSE_GUI
-    wxEnableTopLevelWindows(TRUE);
-    wxEndBusyCursor();
+    }
 #endif // wxUSE_GUI
 
     DWORD dwExitCode = data->dwExitCode;