+
+// ----------------------------------------------------------------------------
+// MyPipedProcess2
+// ----------------------------------------------------------------------------
+
+bool MyPipedProcess2::HasInput()
+{
+ if ( !!m_input )
+ {
+ wxTextOutputStream os(*GetOutputStream());
+ os.WriteString(m_input);
+
+ CloseOutput();
+ m_input.clear();
+
+ // call us once again - may be we'll have output
+ return TRUE;
+ }
+
+ return MyPipedProcess::HasInput();
+}
+
+// ============================================================================
+// MyPipeFrame implementation
+// ============================================================================
+
+MyPipeFrame::MyPipeFrame(wxFrame *parent,
+ const wxString& cmd,
+ wxProcess *process)
+ : wxFrame(parent, -1, cmd),
+ m_process(process),
+ // in a real program we'd check that the streams are !NULL here
+ m_in(*process->GetInputStream()),
+ m_out(*process->GetOutputStream())
+{
+ m_process->SetNextHandler(this);
+
+ wxPanel *panel = new wxPanel(this, -1);
+
+ m_textIn = new wxTextCtrl(panel, -1, _T(""),
+ wxDefaultPosition, wxDefaultSize,
+ wxTE_PROCESS_ENTER);
+ m_textOut = new wxTextCtrl(panel, -1, _T(""));
+ m_textOut->SetEditable(FALSE);
+
+ wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
+ sizerTop->Add(m_textIn, 0, wxGROW | wxALL, 5);
+
+ wxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
+ sizerBtns->Add(new wxButton(panel, Exec_Btn_Send, _T("&Send")), 0,
+ wxALL, 10);
+ sizerBtns->Add(new wxButton(panel, Exec_Btn_Get, _T("&Get")), 0,
+ wxALL, 10);
+
+ sizerTop->Add(sizerBtns, 0, wxCENTRE | wxALL, 5);
+ sizerTop->Add(m_textOut, 0, wxGROW | wxALL, 5);
+
+ panel->SetSizer(sizerTop);
+ sizerTop->Fit(this);
+
+ Show();
+}
+
+void MyPipeFrame::DoGet()
+{
+ // we don't have any way to be notified when any input appears on the
+ // stream so we have to poll it :-(
+ //
+ // NB: this really must be done because otherwise the other program might
+ // not have enough time to receive or process our data and we'd read
+ // an empty string
+ while ( !m_process->IsInputAvailable() && m_process->IsInputOpened() )
+ ;
+
+ m_textOut->SetValue(m_in.ReadLine());
+}
+
+void MyPipeFrame::OnClose(wxCloseEvent& event)
+{
+ if ( m_process )
+ {
+ // we're not interested in getting the process termination notification
+ // if we are closing it ourselves
+ wxProcess *process = m_process;
+ m_process = NULL;
+ process->SetNextHandler(NULL);
+
+ process->CloseOutput();
+ }
+
+ event.Skip();
+}
+
+void MyPipeFrame::OnProcessTerm(wxProcessEvent& event)
+{
+ delete m_process;
+ m_process = NULL;
+
+ wxLogWarning(_T("The other process has terminated, closing"));
+
+ Close();
+}