From 31fb9a577956993e69da16b8b9628420a7c566b1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 25 May 2000 21:54:23 +0000 Subject: [PATCH] 1. stderr redirection seems to work under Windows too (documented new wxProcess method too) 2. don't show the window of the (console) process in wxExecute if IO is redirected 3. implemented wxColourDialog::SetTitle 4. implemented wxGauge95::SetForeground/BackgroundColour() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7491 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/function.tex | 9 ++-- docs/latex/wx/process.tex | 27 ++++++++-- docs/latex/wx/tsamples.tex | 3 ++ docs/latex/wx/wx.hpj | 6 +-- include/wx/msw/colordlg.h | 26 +++++---- include/wx/utils.h | 8 ++- src/common/utilscmn.cpp | 79 ++++++++++++++++++++++----- src/msw/colordlg.cpp | 108 ++++++++++++++++++++++++++----------- src/msw/gauge95.cpp | 71 ++++++++++++++++-------- src/msw/treectrl.cpp | 8 +-- src/msw/utilsexc.cpp | 20 +++++-- 11 files changed, 273 insertions(+), 92 deletions(-) diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index 780c285fa8..3b4823d267 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -1319,6 +1319,8 @@ wxWindows errors. See also \helpref{wxFatalError}{wxfatalerror}. \func{long}{wxExecute}{\param{const wxString\& }{command}, \param{wxArrayString\& }{output}} +\func{long}{wxExecute}{\param{const wxString\& }{command}, \param{wxArrayString\& }{output}, \param{wxArrayString\& }{errors}} + Executes another program in Unix or Windows. The first form takes a command string, such as {\tt "emacs file.txt"}. @@ -1326,8 +1328,8 @@ The first form takes a command string, such as {\tt "emacs file.txt"}. The second form takes an array of values: a command, any number of arguments, terminated by NULL. -The semantics of the third version is different from the first two and is -described in more details below. +The semantics of the third and fourth versions is different from the first two +and is described in more details below. If {\it sync} is FALSE (the default), flow of control immediately returns. If TRUE, the current application waits until the other program has terminated. @@ -1350,7 +1352,8 @@ the process finishes. Finally, you may use the third overloaded version of this function to execute a process (always synchronously) and capture its output in the array -{\it output}. +{\it output}. The fourth version adds the possibility to additionally capture +the messages from standard error output in the {\it errors} array. See also \helpref{wxShell}{wxshell}, \helpref{wxProcess}{wxprocess}, \helpref{Exec sample}{sampleexec}. diff --git a/docs/latex/wx/process.tex b/docs/latex/wx/process.tex index d677829035..95cf13eb19 100644 --- a/docs/latex/wx/process.tex +++ b/docs/latex/wx/process.tex @@ -14,6 +14,15 @@ However, if it is not processed, the object will delete itself and so the library users should only delete those objects whose notifications have been processed (and call \helpref{Detach()}{wxprocessdetach} for others). +wxProcess also supports IO redirection of the child process. For this, you have +to call its \helpref{Redirect}{wxprocessredirect} method before passing it to +\helpref{wxExecute}{wxexecute}. If the child process was launched successfully, +\helpref{GetInputStream}{wxprocessgetinputstream}, +\helpref{GetOutputStream}{wxprocessgetoutputstream} and +\helpref{GetErrorStream}{wxprocessgeterrorstream} can then be used to retrieve +the streams corresponding to the child process stdandard output, input and +error output respectively. + \wxheading{Derived from} \helpref{wxEvtHandler}{wxevthandler} @@ -22,6 +31,11 @@ processed (and call \helpref{Detach()}{wxprocessdetach} for others). +\wxheading{See also} + +\helpref{wxExecute}{wxexecute}\\ +\helpref{exec sample}{sampleexec} + \latexignore{\rtfignore{\wxheading{Members}}} \membersection{wxProcess::wxProcess}\label{wxprocessconstr} @@ -62,19 +76,26 @@ from its parent, no notification events will be sent to the parent and the object will delete itself upon reception of the process termination notification. +\membersection{wxProcess::GetErrorStream}\label{wxprocessgeterrorstream} + +\constfunc{wxInputStream* }{GetErrorStream}{\void} + +Returns an input stream which corresponds to the standard error output (stderr) +of the child process. + \membersection{wxProcess::GetInputStream}\label{wxprocessgetinputstream} \constfunc{wxInputStream* }{GetInputStream}{\void} -It returns a output stream corresponding to the input stream of the subprocess. -If it is NULL, you have not turned on the redirection. +It returns a output stream corresponding to the standard output stream of the +subprocess. If it is NULL, you have not turned on the redirection. See \helpref{wxProcess::Redirect}{wxprocessredirect}. \membersection{wxProcess::GetOutputStream}\label{wxprocessgetoutputstream} \constfunc{wxOutputStream* }{GetOutputStream}{\void} -It returns an output stream correspoding to the output stream of the subprocess. +It returns an output stream correspoding to the input stream of the subprocess. If it is NULL, you have not turned on the redirection. See \helpref{wxProcess::Redirect}{wxprocessredirect}. diff --git a/docs/latex/wx/tsamples.tex b/docs/latex/wx/tsamples.tex index 9ea71aebb9..6c448dc45c 100644 --- a/docs/latex/wx/tsamples.tex +++ b/docs/latex/wx/tsamples.tex @@ -151,6 +151,9 @@ The exec sample demonstrates the \helpref{wxExecute}{wxexecute} and external programs and the sample shows how to do this synchronously (waiting until the program terminates) or asynchronously (notification will come later). +It also shows how to capture the output of the child process in both +synchronous and asynchronous cases. + \subsection{Scroll subwindow sample}\label{samplescrollsub} This sample demonstrates the use of the \helpref{wxScrolledWindow}{wxscrolledwindow} diff --git a/docs/latex/wx/wx.hpj b/docs/latex/wx/wx.hpj index 5bf567ae88..aee3b962f3 100644 --- a/docs/latex/wx/wx.hpj +++ b/docs/latex/wx/wx.hpj @@ -1,14 +1,14 @@ [OPTIONS] -BMROOT=d:\wx2\wxWind~1\docs/latex/wx ; Assume that bitmaps are where the source is +;BMROOT=L:\wxWindows\docs\latex\wx ; Assume that bitmaps are where the source is TITLE=wxWindows Manual CONTENTS=Contents COMPRESS=HIGH [FILES] -wx.rtf +Wx.rtf [CONFIG] -CreateButton("Up", "&Up", "JumpId(`wx.hlp', `Contents')") +CreateButton("Up", "&Up", "JumpId(`Wx.hlp', `Contents')") BrowseButtons() [MAP] diff --git a/include/wx/msw/colordlg.h b/include/wx/msw/colordlg.h index 5643ef6f2f..ae9bcefc37 100644 --- a/include/wx/msw/colordlg.h +++ b/include/wx/msw/colordlg.h @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: colordlg.h +// Name: wx/msw/colordlg.h // Purpose: wxColourDialog class // Author: Julian Smart // Modified by: // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_COLORDLG_H_ @@ -20,25 +20,31 @@ #include "wx/dialog.h" #include "wx/cmndata.h" -/* - * COLOUR DIALOG - */ +// ---------------------------------------------------------------------------- +// wxColourDialog: dialog for choosing a colours +// ---------------------------------------------------------------------------- -class WXDLLEXPORT wxColourDialog: public wxDialog +class WXDLLEXPORT wxColourDialog : public wxDialog { -DECLARE_DYNAMIC_CLASS(wxColourDialog) public: - wxColourDialog(void); + wxColourDialog(); wxColourDialog(wxWindow *parent, wxColourData *data = NULL); bool Create(wxWindow *parent, wxColourData *data = NULL); - int ShowModal(void); - wxColourData& GetColourData(void) { return m_colourData; } + wxColourData& GetColourData() { return m_colourData; } + + // override some base class virtuals + virtual void SetTitle(const wxString& title); + virtual wxString GetTitle(); + virtual int ShowModal(); protected: wxColourData m_colourData; wxWindow* m_dialogParent; + wxString m_title; + + DECLARE_DYNAMIC_CLASS(wxColourDialog) }; #endif diff --git a/include/wx/utils.h b/include/wx/utils.h index e24ce7c2fa..04c5a868ba 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -148,7 +148,13 @@ WXDLLEXPORT long wxExecute(const wxString& command, bool sync = FALSE, wxProcess *process = (wxProcess *) NULL); // execute the command capturing its output into an array line by line -WXDLLEXPORT long wxExecute(const wxString& command, wxArrayString& output); +WXDLLEXPORT long wxExecute(const wxString& command, + wxArrayString& output); + +// also capture stderr +WXDLLEXPORT long wxExecute(const wxString& command, + wxArrayString& output, + wxArrayString& error); enum wxSignal { diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 28fc29f693..5ddfb2442a 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -1208,12 +1208,18 @@ wxString wxGetCurrentDir() // wxExecute // ---------------------------------------------------------------------------- -long wxExecute(const wxString& command, wxArrayString& output) +// this is a private function because it hasn't a clean interface: the first +// array is passed by reference, the second by pointer - instead we have 2 +// public versions of wxExecute() below +static long wxDoExecuteWithCapture(const wxString& command, + wxArrayString& output, + wxArrayString* error) { #ifdef __WIN16__ wxFAIL_MSG("Sorry, this version of wxExecute not implemented on WIN16."); + return 0; -#else +#else // !Win16 // create a wxProcess which will capture the output wxProcess *process = new wxProcess; process->Redirect(); @@ -1223,19 +1229,68 @@ long wxExecute(const wxString& command, wxArrayString& output) #if wxUSE_STREAMS if ( rc != -1 ) { - wxInputStream& is = *process->GetInputStream(); - wxTextInputStream tis(is); - while ( !is.Eof() && is.IsOk() ) - { - wxString line = tis.ReadLine(); - if ( is.LastError() ) - break; + wxInputStream* is = process->GetInputStream(); + wxCHECK_MSG( is, -1, _T("if wxExecute() succeded, stream can't be NULL") ); + wxTextInputStream tis(*is); - output.Add(line); + wxTextInputStream *tes = NULL; + wxInputStream *es = NULL; + if ( error ) + { + es = process->GetErrorStream(); + + wxCHECK_MSG( es, -1, _T("stderr can't be NULL") ); + + tes = new wxTextInputStream(*es); } + + bool cont; + do + { + cont = FALSE; + + if ( !is->Eof() && is->IsOk() ) + { + wxString line = tis.ReadLine(); + if ( is->LastError() ) + break; + + cont = TRUE; + + output.Add(line); + } + + if ( error && !es->Eof() && es->IsOk() ) + { + wxString line = tes->ReadLine(); + if ( es->LastError() ) + break; + + cont = TRUE; + + error->Add(line); + } + } + while ( cont ); + + delete tes; } -#endif +#endif // wxUSE_STREAMS + + delete process; return rc; -#endif +#endif // IO redirection supoprted +} + +long wxExecute(const wxString& command, wxArrayString& output) +{ + return wxDoExecuteWithCapture(command, output, NULL); +} + +long wxExecute(const wxString& command, + wxArrayString& output, + wxArrayString& error) +{ + return wxDoExecuteWithCapture(command, output, &error); } diff --git a/src/msw/colordlg.cpp b/src/msw/colordlg.cpp index 66e0a3ef73..3d5f0ecf77 100644 --- a/src/msw/colordlg.cpp +++ b/src/msw/colordlg.cpp @@ -1,43 +1,51 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: colordlg.cpp +// Name: src/msw/colordlg.cpp // Purpose: wxColourDialog class // Author: Julian Smart // Modified by: // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "colordlg.h" + #pragma implementation "colordlg.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #ifndef WX_PRECOMP -#include -#include "wx/defs.h" -#include "wx/bitmap.h" -#include "wx/pen.h" -#include "wx/brush.h" -#include "wx/colour.h" -#include "wx/gdicmn.h" -#include "wx/utils.h" -#include "wx/frame.h" -#include "wx/dialog.h" -#include "wx/msgdlg.h" + #include + #include "wx/defs.h" + #include "wx/bitmap.h" + #include "wx/pen.h" + #include "wx/brush.h" + #include "wx/colour.h" + #include "wx/gdicmn.h" + #include "wx/utils.h" + #include "wx/frame.h" + #include "wx/dialog.h" + #include "wx/msgdlg.h" #endif #include #if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__) -#include + #include #endif #include "wx/msw/private.h" @@ -48,16 +56,41 @@ #include #include -#define wxDIALOG_DEFAULT_X 300 -#define wxDIALOG_DEFAULT_Y 300 +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog) -/* - * wxColourDialog - */ +// ============================================================================ +// implementation +// ============================================================================ -wxColourDialog::wxColourDialog(void) +// ---------------------------------------------------------------------------- +// colour dialog hook proc +// ---------------------------------------------------------------------------- + +UINT CALLBACK wxColourDialogHookProc(HWND hwnd, + UINT uiMsg, + WPARAM wParam, + LPARAM lParam) +{ + if ( uiMsg == WM_INITDIALOG ) + { + CHOOSECOLOR *pCC = (CHOOSECOLOR *)lParam; + wxColourDialog *dialog = (wxColourDialog *)pCC->lCustData; + + ::SetWindowText(hwnd, dialog->GetTitle()); + } + + return 0; +} + +// ---------------------------------------------------------------------------- +// wxColourDialog +// ---------------------------------------------------------------------------- + +wxColourDialog::wxColourDialog() { m_dialogParent = NULL; } @@ -76,7 +109,7 @@ bool wxColourDialog::Create(wxWindow *parent, wxColourData *data) return TRUE; } -int wxColourDialog::ShowModal(void) +int wxColourDialog::ShowModal() { CHOOSECOLOR chooseColorStruct; COLORREF custColours[16]; @@ -84,20 +117,23 @@ int wxColourDialog::ShowModal(void) int i; for (i = 0; i < 16; i++) - custColours[i] = RGB(m_colourData.custColours[i].Red(), m_colourData.custColours[i].Green(), m_colourData.custColours[i].Blue()); + custColours[i] = wxColourToRGB(m_colourData.custColours[i]); chooseColorStruct.lStructSize = sizeof(CHOOSECOLOR); - chooseColorStruct.hwndOwner = (HWND) (m_dialogParent ? (HWND) m_dialogParent->GetHWND() : (HWND) NULL); - chooseColorStruct.rgbResult = RGB(m_colourData.dataColour.Red(), m_colourData.dataColour.Green(), m_colourData.dataColour.Blue()); + if ( m_dialogParent ) + chooseColorStruct.hwndOwner = GetHwndOf(m_dialogParent); + chooseColorStruct.rgbResult = wxColourToRGB(m_colourData.dataColour); chooseColorStruct.lpCustColors = custColours; - chooseColorStruct.Flags = CC_RGBINIT; + chooseColorStruct.Flags = CC_RGBINIT | CC_ENABLEHOOK; + chooseColorStruct.lCustData = (LPARAM)this; + chooseColorStruct.lpfnHook = wxColourDialogHookProc; if (!m_colourData.GetChooseFull()) chooseColorStruct.Flags |= CC_PREVENTFULLOPEN; // Do the modal dialog - bool success = (ChooseColor(&(chooseColorStruct)) != 0); + bool success = ::ChooseColor(&(chooseColorStruct)) != 0; // Try to highlight the correct window (the parent) HWND hWndParent = 0; @@ -112,13 +148,21 @@ int wxColourDialog::ShowModal(void) // Restore values for (i = 0; i < 16; i++) { - m_colourData.custColours[i].Set(GetRValue(custColours[i]), GetGValue(custColours[i]), - GetBValue(custColours[i])); + wxRGBToColour(m_colourData.custColours[i], custColours[i]); } - m_colourData.dataColour.Set(GetRValue(chooseColorStruct.rgbResult), GetGValue(chooseColorStruct.rgbResult), - GetBValue(chooseColorStruct.rgbResult)); + wxRGBToColour(m_colourData.dataColour, chooseColorStruct.rgbResult); return success ? wxID_OK : wxID_CANCEL; } +void wxColourDialog::SetTitle(const wxString& title) +{ + m_title = title; +} + +wxString wxColourDialog::GetTitle() +{ + return m_title; +} + diff --git a/src/msw/gauge95.cpp b/src/msw/gauge95.cpp index 18d6f85897..4f1bff7201 100644 --- a/src/msw/gauge95.cpp +++ b/src/msw/gauge95.cpp @@ -1,16 +1,24 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: gauge95.cpp +// Name: src/msw/gauge95.cpp // Purpose: wxGauge95 class // Author: Julian Smart // Modified by: // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "gauge95.h" + #pragma implementation "gauge95.h" #endif // For compilers that support precompilation, includes "wx.h". @@ -21,7 +29,7 @@ #endif #ifndef WX_PRECOMP -#include "wx/defs.h" + #include "wx/defs.h" #endif #if wxUSE_GAUGE && defined(__WIN95__) @@ -33,8 +41,37 @@ #include #endif +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// old commctrl.h (< 4.71) don't have those +#ifndef PBS_SMOOTH + #define PBS_SMOOTH 0x01 +#endif + +#ifndef PBS_VERTICAL + #define PBS_VERTICAL 0x04 +#endif + +#ifndef PBM_SETBARCOLOR + #define PBM_SETBARCOLOR (WM_USER+9) +#endif + +#ifndef PBM_SETBKCOLOR + #define PBM_SETBKCOLOR 0x2001 +#endif + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + IMPLEMENT_DYNAMIC_CLASS(wxGauge95, wxControl) +// ============================================================================ +// implementation +// ============================================================================ + bool wxGauge95::Create(wxWindow *parent, wxWindowID id, int range, const wxPoint& pos, @@ -52,8 +89,8 @@ bool wxGauge95::Create(wxWindow *parent, wxWindowID id, m_rangeMax = range; m_gaugePos = 0; - SetBackgroundColour(parent->GetBackgroundColour()) ; - SetForegroundColour(parent->GetForegroundColour()) ; + SetBackgroundColour(parent->GetBackgroundColour()); + SetForegroundColour(parent->GetForegroundColour()); m_windowStyle = style; @@ -67,19 +104,11 @@ bool wxGauge95::Create(wxWindow *parent, wxWindowID id, int width = size.x; int height = size.y; - long msFlags = WS_CHILD | WS_VISIBLE /* | WS_CLIPSIBLINGS */ ; - -#ifndef PBS_VERTICAL -#define PBS_VERTICAL 0x04 -#endif + long msFlags = WS_CHILD | WS_VISIBLE /* | WS_CLIPSIBLINGS */; if (m_windowStyle & wxGA_VERTICAL) msFlags |= PBS_VERTICAL; -#ifndef PBS_SMOOTH -#define PBS_SMOOTH 0x01 -#endif - if (m_windowStyle & wxGA_SMOOTH) msFlags |= PBS_SMOOTH; @@ -130,22 +159,22 @@ void wxGauge95::SetValue(int pos) SendMessage((HWND) GetHWND(), PBM_SETPOS, pos, 0); } -int wxGauge95::GetShadowWidth(void) const +int wxGauge95::GetShadowWidth() const { return 0; } -int wxGauge95::GetBezelFace(void) const +int wxGauge95::GetBezelFace() const { return 0; } -int wxGauge95::GetRange(void) const +int wxGauge95::GetRange() const { return m_rangeMax; } -int wxGauge95::GetValue(void) const +int wxGauge95::GetValue() const { return m_gaugePos; } @@ -155,7 +184,7 @@ bool wxGauge95::SetForegroundColour(const wxColour& col) if ( !wxControl::SetForegroundColour(col) ) return FALSE; - m_foregroundColour = col ; + SendMessage(GetHwnd(), PBM_SETBARCOLOR, 0, (LPARAM)wxColourToRGB(col)); return TRUE; } @@ -165,7 +194,7 @@ bool wxGauge95::SetBackgroundColour(const wxColour& col) if ( !wxControl::SetBackgroundColour(col) ) return FALSE; - m_backgroundColour = col ; + SendMessage(GetHwnd(), PBM_SETBKCOLOR, 0, (LPARAM)wxColourToRGB(col)); return TRUE; } diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 17de6a6068..9bbb661b03 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -2218,9 +2218,11 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) switch ( hdr->code ) { case NM_DBLCLK: - // return TRUE to prevent the default processing which consists in - // toggling the state of the item under the mouse - *result = processed; + // we translate NM_DBLCLK into ACTIVATED event, so don't interpret + // the return code of this event handler as the return value for + // NM_DBLCLK - otherwise, double clicking the item to toggle its + // expanded status would never work + *result = FALSE; break; case TVN_BEGINDRAG: diff --git a/src/msw/utilsexc.cpp b/src/msw/utilsexc.cpp index 09049b1e55..105305a563 100644 --- a/src/msw/utilsexc.cpp +++ b/src/msw/utilsexc.cpp @@ -398,7 +398,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) #if wxUSE_STREAMS // the first elements are reading ends, the second are the writing ones HANDLE hpipeStdin[2], - hpipeStdout[2]; + hpipeStdout[2], + hpipeStderr[2]; // open the pipes to which child process IO will be redirected if needed if ( handler && handler->IsRedirected() ) @@ -430,6 +431,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) return sync ? -1 : 0; } + (void)::CreatePipe(&hpipeStderr[0], &hpipeStderr[1], &security, 0); + redirect = TRUE; } #endif // wxUSE_STREAMS @@ -442,9 +445,15 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) #if wxUSE_STREAMS if ( redirect ) { - si.dwFlags = STARTF_USESTDHANDLES; + // when the std IO is redirected, we don't show the (console) process + // window + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.hStdInput = hpipeStdin[0]; si.hStdOutput = hpipeStdout[1]; + si.hStdError = hpipeStderr[1]; + + si.wShowWindow = SW_HIDE; } #endif // wxUSE_STREAMS @@ -472,6 +481,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) { ::CloseHandle(hpipeStdin[0]); ::CloseHandle(hpipeStdout[1]); + ::CloseHandle(hpipeStderr[1]); } #endif // wxUSE_STREAMS @@ -483,6 +493,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) { ::CloseHandle(hpipeStdin[1]); ::CloseHandle(hpipeStdout[0]); + ::CloseHandle(hpipeStderr[0]); } #endif // wxUSE_STREAMS @@ -495,10 +506,11 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler) if ( redirect ) { // We can now initialize the wxStreams - wxInputStream *inStream = new wxPipeInputStream(hpipeStdout[0]); + wxInputStream *inStream = new wxPipeInputStream(hpipeStdout[0]), + *errStream = new wxPipeInputStream(hpipeStderr[0]); wxOutputStream *outStream = new wxPipeOutputStream(hpipeStdin[1]); - handler->SetPipeStreams(inStream, outStream, NULL); + handler->SetPipeStreams(inStream, outStream, errStream); } #endif // wxUSE_STREAMS