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}, \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}.

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
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).
<wx/process.h>
\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}.

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
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}

View File

@@ -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]

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: colordlg.h
// Name: wx/msw/colordlg.h
// Purpose: wxColourDialog class
// Author: Julian Smart
// Modified by:
@@ -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

View File

@@ -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
{

View File

@@ -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() )
wxInputStream* is = process->GetInputStream();
wxCHECK_MSG( is, -1, _T("if wxExecute() succeded, stream can't be NULL") );
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();
if ( is.LastError() )
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);
}
#endif
}
while ( cont );
delete tes;
}
#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);
}

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: colordlg.cpp
// Name: src/msw/colordlg.cpp
// Purpose: wxColourDialog class
// Author: Julian Smart
// Modified by:
@@ -9,35 +9,43 @@
// 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 <stdio.h>
#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 <stdio.h>
#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 <windows.h>
#if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__)
#include <commdlg.h>
#include <commdlg.h>
#endif
#include "wx/msw/private.h"
@@ -48,16 +56,41 @@
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: gauge95.cpp
// Name: src/msw/gauge95.cpp
// Purpose: wxGauge95 class
// Author: Julian Smart
// Modified by:
@@ -9,8 +9,16 @@
// 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 <commctrl.h>
#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;
}

View File

@@ -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:

View File

@@ -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