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
This commit is contained in:
Vadim Zeitlin
2000-05-25 21:54:23 +00:00
parent 54d5ffd6c3
commit 31fb9a5779
11 changed files with 273 additions and 92 deletions

View File

@@ -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}}
\func{long}{wxExecute}{\param{const wxString\& }{command}, \param{wxArrayString\& }{output}, \param{wxArrayString\& }{errors}}
Executes another program in Unix or Windows. Executes another program in Unix or Windows.
The first form takes a command string, such as {\tt "emacs file.txt"}. 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 The second form takes an array of values: a command, any number of
arguments, terminated by NULL. arguments, terminated by NULL.
The semantics of the third version is different from the first two and is The semantics of the third and fourth versions is different from the first two
described in more details below. and is described in more details below.
If {\it sync} is FALSE (the default), flow of control immediately returns. If {\it sync} is FALSE (the default), flow of control immediately returns.
If TRUE, the current application waits until the other program has terminated. 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 Finally, you may use the third overloaded version of this function to execute
a process (always synchronously) and capture its output in the array 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}, See also \helpref{wxShell}{wxshell}, \helpref{wxProcess}{wxprocess},
\helpref{Exec sample}{sampleexec}. \helpref{Exec sample}{sampleexec}.

View File

@@ -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 library users should only delete those objects whose notifications have been
processed (and call \helpref{Detach()}{wxprocessdetach} for others). 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} \wxheading{Derived from}
\helpref{wxEvtHandler}{wxevthandler} \helpref{wxEvtHandler}{wxevthandler}
@@ -22,6 +31,11 @@ processed (and call \helpref{Detach()}{wxprocessdetach} for others).
<wx/process.h> <wx/process.h>
\wxheading{See also}
\helpref{wxExecute}{wxexecute}\\
\helpref{exec sample}{sampleexec}
\latexignore{\rtfignore{\wxheading{Members}}} \latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxProcess::wxProcess}\label{wxprocessconstr} \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 object will delete itself upon reception of the process termination
notification. 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} \membersection{wxProcess::GetInputStream}\label{wxprocessgetinputstream}
\constfunc{wxInputStream* }{GetInputStream}{\void} \constfunc{wxInputStream* }{GetInputStream}{\void}
It returns a output stream corresponding to the input stream of the subprocess. It returns a output stream corresponding to the standard output stream of the
If it is NULL, you have not turned on the redirection. subprocess. If it is NULL, you have not turned on the redirection.
See \helpref{wxProcess::Redirect}{wxprocessredirect}. See \helpref{wxProcess::Redirect}{wxprocessredirect}.
\membersection{wxProcess::GetOutputStream}\label{wxprocessgetoutputstream} \membersection{wxProcess::GetOutputStream}\label{wxprocessgetoutputstream}
\constfunc{wxOutputStream* }{GetOutputStream}{\void} \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. If it is NULL, you have not turned on the redirection.
See \helpref{wxProcess::Redirect}{wxprocessredirect}. See \helpref{wxProcess::Redirect}{wxprocessredirect}.

View File

@@ -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 external programs and the sample shows how to do this synchronously (waiting
until the program terminates) or asynchronously (notification will come later). 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} \subsection{Scroll subwindow sample}\label{samplescrollsub}
This sample demonstrates the use of the \helpref{wxScrolledWindow}{wxscrolledwindow} This sample demonstrates the use of the \helpref{wxScrolledWindow}{wxscrolledwindow}

View File

@@ -1,14 +1,14 @@
[OPTIONS] [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 TITLE=wxWindows Manual
CONTENTS=Contents CONTENTS=Contents
COMPRESS=HIGH COMPRESS=HIGH
[FILES] [FILES]
wx.rtf Wx.rtf
[CONFIG] [CONFIG]
CreateButton("Up", "&Up", "JumpId(`wx.hlp', `Contents')") CreateButton("Up", "&Up", "JumpId(`Wx.hlp', `Contents')")
BrowseButtons() BrowseButtons()
[MAP] [MAP]

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: colordlg.h // Name: wx/msw/colordlg.h
// Purpose: wxColourDialog class // Purpose: wxColourDialog class
// Author: Julian Smart // Author: Julian Smart
// Modified by: // Modified by:
@@ -20,25 +20,31 @@
#include "wx/dialog.h" #include "wx/dialog.h"
#include "wx/cmndata.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: public:
wxColourDialog(void); wxColourDialog();
wxColourDialog(wxWindow *parent, wxColourData *data = NULL); wxColourDialog(wxWindow *parent, wxColourData *data = NULL);
bool Create(wxWindow *parent, wxColourData *data = NULL); bool Create(wxWindow *parent, wxColourData *data = NULL);
int ShowModal(void); wxColourData& GetColourData() { return m_colourData; }
wxColourData& GetColourData(void) { return m_colourData; }
// override some base class virtuals
virtual void SetTitle(const wxString& title);
virtual wxString GetTitle();
virtual int ShowModal();
protected: protected:
wxColourData m_colourData; wxColourData m_colourData;
wxWindow* m_dialogParent; wxWindow* m_dialogParent;
wxString m_title;
DECLARE_DYNAMIC_CLASS(wxColourDialog)
}; };
#endif #endif

View File

@@ -148,7 +148,13 @@ WXDLLEXPORT long wxExecute(const wxString& command, bool sync = FALSE,
wxProcess *process = (wxProcess *) NULL); wxProcess *process = (wxProcess *) NULL);
// execute the command capturing its output into an array line by line // 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 enum wxSignal
{ {

View File

@@ -1208,12 +1208,18 @@ wxString wxGetCurrentDir()
// wxExecute // 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__ #ifdef __WIN16__
wxFAIL_MSG("Sorry, this version of wxExecute not implemented on WIN16."); wxFAIL_MSG("Sorry, this version of wxExecute not implemented on WIN16.");
return 0; return 0;
#else #else // !Win16
// create a wxProcess which will capture the output // create a wxProcess which will capture the output
wxProcess *process = new wxProcess; wxProcess *process = new wxProcess;
process->Redirect(); process->Redirect();
@@ -1223,19 +1229,68 @@ long wxExecute(const wxString& command, wxArrayString& output)
#if wxUSE_STREAMS #if wxUSE_STREAMS
if ( rc != -1 ) if ( rc != -1 )
{ {
wxInputStream& is = *process->GetInputStream(); wxInputStream* is = process->GetInputStream();
wxTextInputStream tis(is); wxCHECK_MSG( is, -1, _T("if wxExecute() succeded, stream can't be NULL") );
while ( !is.Eof() && is.IsOk() ) wxTextInputStream tis(*is);
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(); wxString line = tis.ReadLine();
if ( is.LastError() ) if ( is->LastError() )
break; break;
cont = TRUE;
output.Add(line); output.Add(line);
} }
if ( error && !es->Eof() && es->IsOk() )
{
wxString line = tes->ReadLine();
if ( es->LastError() )
break;
cont = TRUE;
error->Add(line);
} }
#endif }
while ( cont );
delete tes;
}
#endif // wxUSE_STREAMS
delete process;
return rc; 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);
} }

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: colordlg.cpp // Name: src/msw/colordlg.cpp
// Purpose: wxColourDialog class // Purpose: wxColourDialog class
// Author: Julian Smart // Author: Julian Smart
// Modified by: // Modified by:
@@ -9,6 +9,14 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "colordlg.h" #pragma implementation "colordlg.h"
#endif #endif
@@ -48,16 +56,41 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define wxDIALOG_DEFAULT_X 300 // ----------------------------------------------------------------------------
#define wxDIALOG_DEFAULT_Y 300 // wxWin macros
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog) 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; m_dialogParent = NULL;
} }
@@ -76,7 +109,7 @@ bool wxColourDialog::Create(wxWindow *parent, wxColourData *data)
return TRUE; return TRUE;
} }
int wxColourDialog::ShowModal(void) int wxColourDialog::ShowModal()
{ {
CHOOSECOLOR chooseColorStruct; CHOOSECOLOR chooseColorStruct;
COLORREF custColours[16]; COLORREF custColours[16];
@@ -84,20 +117,23 @@ int wxColourDialog::ShowModal(void)
int i; int i;
for (i = 0; i < 16; 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.lStructSize = sizeof(CHOOSECOLOR);
chooseColorStruct.hwndOwner = (HWND) (m_dialogParent ? (HWND) m_dialogParent->GetHWND() : (HWND) NULL); if ( m_dialogParent )
chooseColorStruct.rgbResult = RGB(m_colourData.dataColour.Red(), m_colourData.dataColour.Green(), m_colourData.dataColour.Blue()); chooseColorStruct.hwndOwner = GetHwndOf(m_dialogParent);
chooseColorStruct.rgbResult = wxColourToRGB(m_colourData.dataColour);
chooseColorStruct.lpCustColors = custColours; chooseColorStruct.lpCustColors = custColours;
chooseColorStruct.Flags = CC_RGBINIT; chooseColorStruct.Flags = CC_RGBINIT | CC_ENABLEHOOK;
chooseColorStruct.lCustData = (LPARAM)this;
chooseColorStruct.lpfnHook = wxColourDialogHookProc;
if (!m_colourData.GetChooseFull()) if (!m_colourData.GetChooseFull())
chooseColorStruct.Flags |= CC_PREVENTFULLOPEN; chooseColorStruct.Flags |= CC_PREVENTFULLOPEN;
// Do the modal dialog // Do the modal dialog
bool success = (ChooseColor(&(chooseColorStruct)) != 0); bool success = ::ChooseColor(&(chooseColorStruct)) != 0;
// Try to highlight the correct window (the parent) // Try to highlight the correct window (the parent)
HWND hWndParent = 0; HWND hWndParent = 0;
@@ -112,13 +148,21 @@ int wxColourDialog::ShowModal(void)
// Restore values // Restore values
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
m_colourData.custColours[i].Set(GetRValue(custColours[i]), GetGValue(custColours[i]), wxRGBToColour(m_colourData.custColours[i], custColours[i]);
GetBValue(custColours[i]));
} }
m_colourData.dataColour.Set(GetRValue(chooseColorStruct.rgbResult), GetGValue(chooseColorStruct.rgbResult), wxRGBToColour(m_colourData.dataColour, chooseColorStruct.rgbResult);
GetBValue(chooseColorStruct.rgbResult));
return success ? wxID_OK : wxID_CANCEL; return success ? wxID_OK : wxID_CANCEL;
} }
void wxColourDialog::SetTitle(const wxString& title)
{
m_title = title;
}
wxString wxColourDialog::GetTitle()
{
return m_title;
}

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: gauge95.cpp // Name: src/msw/gauge95.cpp
// Purpose: wxGauge95 class // Purpose: wxGauge95 class
// Author: Julian Smart // Author: Julian Smart
// Modified by: // Modified by:
@@ -9,6 +9,14 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "gauge95.h" #pragma implementation "gauge95.h"
#endif #endif
@@ -33,8 +41,37 @@
#include <commctrl.h> #include <commctrl.h>
#endif #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) IMPLEMENT_DYNAMIC_CLASS(wxGauge95, wxControl)
// ============================================================================
// implementation
// ============================================================================
bool wxGauge95::Create(wxWindow *parent, wxWindowID id, bool wxGauge95::Create(wxWindow *parent, wxWindowID id,
int range, int range,
const wxPoint& pos, const wxPoint& pos,
@@ -69,17 +106,9 @@ bool wxGauge95::Create(wxWindow *parent, wxWindowID id,
long msFlags = WS_CHILD | WS_VISIBLE /* | WS_CLIPSIBLINGS */; long msFlags = WS_CHILD | WS_VISIBLE /* | WS_CLIPSIBLINGS */;
#ifndef PBS_VERTICAL
#define PBS_VERTICAL 0x04
#endif
if (m_windowStyle & wxGA_VERTICAL) if (m_windowStyle & wxGA_VERTICAL)
msFlags |= PBS_VERTICAL; msFlags |= PBS_VERTICAL;
#ifndef PBS_SMOOTH
#define PBS_SMOOTH 0x01
#endif
if (m_windowStyle & wxGA_SMOOTH) if (m_windowStyle & wxGA_SMOOTH)
msFlags |= PBS_SMOOTH; msFlags |= PBS_SMOOTH;
@@ -130,22 +159,22 @@ void wxGauge95::SetValue(int pos)
SendMessage((HWND) GetHWND(), PBM_SETPOS, pos, 0); SendMessage((HWND) GetHWND(), PBM_SETPOS, pos, 0);
} }
int wxGauge95::GetShadowWidth(void) const int wxGauge95::GetShadowWidth() const
{ {
return 0; return 0;
} }
int wxGauge95::GetBezelFace(void) const int wxGauge95::GetBezelFace() const
{ {
return 0; return 0;
} }
int wxGauge95::GetRange(void) const int wxGauge95::GetRange() const
{ {
return m_rangeMax; return m_rangeMax;
} }
int wxGauge95::GetValue(void) const int wxGauge95::GetValue() const
{ {
return m_gaugePos; return m_gaugePos;
} }
@@ -155,7 +184,7 @@ bool wxGauge95::SetForegroundColour(const wxColour& col)
if ( !wxControl::SetForegroundColour(col) ) if ( !wxControl::SetForegroundColour(col) )
return FALSE; return FALSE;
m_foregroundColour = col ; SendMessage(GetHwnd(), PBM_SETBARCOLOR, 0, (LPARAM)wxColourToRGB(col));
return TRUE; return TRUE;
} }
@@ -165,7 +194,7 @@ bool wxGauge95::SetBackgroundColour(const wxColour& col)
if ( !wxControl::SetBackgroundColour(col) ) if ( !wxControl::SetBackgroundColour(col) )
return FALSE; return FALSE;
m_backgroundColour = col ; SendMessage(GetHwnd(), PBM_SETBKCOLOR, 0, (LPARAM)wxColourToRGB(col));
return TRUE; return TRUE;
} }

View File

@@ -2218,9 +2218,11 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
switch ( hdr->code ) switch ( hdr->code )
{ {
case NM_DBLCLK: case NM_DBLCLK:
// return TRUE to prevent the default processing which consists in // we translate NM_DBLCLK into ACTIVATED event, so don't interpret
// toggling the state of the item under the mouse // the return code of this event handler as the return value for
*result = processed; // NM_DBLCLK - otherwise, double clicking the item to toggle its
// expanded status would never work
*result = FALSE;
break; break;
case TVN_BEGINDRAG: case TVN_BEGINDRAG:

View File

@@ -398,7 +398,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
#if wxUSE_STREAMS #if wxUSE_STREAMS
// the first elements are reading ends, the second are the writing ones // the first elements are reading ends, the second are the writing ones
HANDLE hpipeStdin[2], HANDLE hpipeStdin[2],
hpipeStdout[2]; hpipeStdout[2],
hpipeStderr[2];
// open the pipes to which child process IO will be redirected if needed // open the pipes to which child process IO will be redirected if needed
if ( handler && handler->IsRedirected() ) if ( handler && handler->IsRedirected() )
@@ -430,6 +431,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
return sync ? -1 : 0; return sync ? -1 : 0;
} }
(void)::CreatePipe(&hpipeStderr[0], &hpipeStderr[1], &security, 0);
redirect = TRUE; redirect = TRUE;
} }
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS
@@ -442,9 +445,15 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
#if wxUSE_STREAMS #if wxUSE_STREAMS
if ( redirect ) 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.hStdInput = hpipeStdin[0];
si.hStdOutput = hpipeStdout[1]; si.hStdOutput = hpipeStdout[1];
si.hStdError = hpipeStderr[1];
si.wShowWindow = SW_HIDE;
} }
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS
@@ -472,6 +481,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
{ {
::CloseHandle(hpipeStdin[0]); ::CloseHandle(hpipeStdin[0]);
::CloseHandle(hpipeStdout[1]); ::CloseHandle(hpipeStdout[1]);
::CloseHandle(hpipeStderr[1]);
} }
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS
@@ -483,6 +493,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
{ {
::CloseHandle(hpipeStdin[1]); ::CloseHandle(hpipeStdin[1]);
::CloseHandle(hpipeStdout[0]); ::CloseHandle(hpipeStdout[0]);
::CloseHandle(hpipeStderr[0]);
} }
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS
@@ -495,10 +506,11 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
if ( redirect ) if ( redirect )
{ {
// We can now initialize the wxStreams // 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]); wxOutputStream *outStream = new wxPipeOutputStream(hpipeStdin[1]);
handler->SetPipeStreams(inStream, outStream, NULL); handler->SetPipeStreams(inStream, outStream, errStream);
} }
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS