Inserted "stdio catch" in wxExecute. The activation is controlled by wxProcess.

Completed some TODO in wxMMedia (wxSoundUlaw, ...)
Reworked the PCM converted: it should be simpler to add converters now and it is
cleaner.
Implemented status information in wxVideoWindows but it doesn't work on my
Win98SE (UNSUPPORTED_FUNCTION)
Changed *ERR into *ERROR
Added a TODO: we must detect the best format in wxSoundWindows


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6311 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
2000-02-27 10:44:49 +00:00
parent bdeca1d18c
commit 8b33ae2d5a
23 changed files with 1148 additions and 563 deletions

View File

@@ -37,6 +37,7 @@
#include "wx/log.h"
#ifdef __WIN32__
#include "wx/stream.h"
#include "wx/process.h"
#endif
@@ -120,6 +121,94 @@ public:
bool state; // set to FALSE when the process finishes
};
#ifdef __WIN32__
// ----------------------------------------------------------------------------
// wxPipeStreams
// ----------------------------------------------------------------------------
class wxPipeInputStream: public wxInputStream {
public:
wxPipeInputStream(HANDLE hInput);
~wxPipeInputStream();
protected:
size_t OnSysRead(void *buffer, size_t len);
protected:
HANDLE m_hInput;
};
class wxPipeOutputStream: public wxOutputStream {
public:
wxPipeOutputStream(HANDLE hOutput);
~wxPipeOutputStream();
protected:
size_t OnSysWrite(const void *buffer, size_t len);
protected:
HANDLE m_hOutput;
};
// ==================
// wxPipeInputStream
// ==================
wxPipeInputStream::wxPipeInputStream(HANDLE hInput)
{
m_hInput = hInput;
}
wxPipeInputStream::~wxPipeInputStream()
{
::CloseHandle(m_hInput);
}
size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len)
{
DWORD bytesRead;
m_lasterror = wxSTREAM_NOERROR;
if (! ::ReadFile(m_hInput, buffer, len, &bytesRead, NULL) ) {
if (GetLastError() == ERROR_BROKEN_PIPE)
m_lasterror = wxSTREAM_EOF;
else
m_lasterror = wxSTREAM_READ_ERROR;
}
return bytesRead;
}
// ==================
// wxPipeOutputStream
// ==================
wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput)
{
m_hOutput = hOutput;
}
wxPipeOutputStream::~wxPipeOutputStream()
{
::CloseHandle(m_hOutput);
}
size_t wxPipeOutputStream::OnSysWrite(const void *buffer, size_t len)
{
DWORD bytesRead;
m_lasterror = wxSTREAM_NOERROR;
if (! ::WriteFile(m_hOutput, buffer, len, &bytesRead, NULL) ) {
if (GetLastError() == ERROR_BROKEN_PIPE)
m_lasterror = wxSTREAM_EOF;
else
m_lasterror = wxSTREAM_READ_ERROR;
}
return bytesRead;
}
#endif // __WIN32__
// ============================================================================
// implementation
// ============================================================================
@@ -289,7 +378,6 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
// only reached for space not inside quotes
break;
}
wxString commandArgs = pc;
wxWindow *winTop = wxTheApp->GetTopWindow();
@@ -313,6 +401,46 @@ 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()) {
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"));
return 0;
}
if (! ::CreatePipe(&h_writePipe[0], &h_writePipe[1], &security, 0) ) {
wxLogSysError(_T("Can't create the inter-process read 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);
SetStdHandle(STD_INPUT_HANDLE, h_readPipe[0]);
SetStdHandle(STD_OUTPUT_HANDLE, h_writePipe[1]);
inheritHandles = TRUE;
}
// create the process
STARTUPINFO si;
@@ -327,7 +455,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
(wxChar *)command.c_str(), // full command line
NULL, // security attributes: defaults for both
NULL, // the process and its main thread
FALSE, // don't inherit handles
inheritHandles, // inherit handles if we need pipes
CREATE_DEFAULT_ERROR_MODE |
CREATE_SUSPENDED, // flags
NULL, // environment (use the same)
@@ -336,11 +464,31 @@ 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]);
}
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);
::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]);
handler->SetPipeStreams(processOutput, processInput);
}
// register the class for the hidden window used for the notifications
if ( !gs_classForHiddenWindow )
{