1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: exec sample demonstrates wxExecute and related functions
4 // Author: Vadim Zeitlin
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "exec.cpp"
22 #pragma interface "exec.cpp"
25 // For compilers that support precompilation, includes "wx/wx.h".
26 #include "wx/wxprec.h"
32 // for all others, include the necessary headers (this file is usually all you
33 // need because it includes almost all "standard" wxWindows headers
39 #include "wx/msgdlg.h"
40 #include "wx/textdlg.h"
41 #include "wx/listbox.h"
44 #include "wx/txtstrm.h"
46 #include "wx/process.h"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 // Define a new application type, each program should derive a class from wxApp
57 class MyApp
: public wxApp
60 // override base class virtuals
61 // ----------------------------
63 // this one is called on application startup and is a good place for the app
64 // initialization (doing it here and not in the ctor allows to have an error
65 // return: if OnInit() returns false, the application terminates)
66 virtual bool OnInit();
69 // Define a new frame type: this is going to be our main frame
70 class MyFrame
: public wxFrame
74 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
76 // event handlers (these functions should _not_ be virtual)
77 void OnQuit(wxCommandEvent
& event
);
79 void OnClear(wxCommandEvent
& event
);
81 void OnSyncExec(wxCommandEvent
& event
);
82 void OnAsyncExec(wxCommandEvent
& event
);
83 void OnShell(wxCommandEvent
& event
);
84 void OnExecWithRedirect(wxCommandEvent
& event
);
85 void OnDDEExec(wxCommandEvent
& event
);
87 void OnAbout(wxCommandEvent
& event
);
90 wxListBox
*GetLogListBox() const { return m_lbox
; }
97 // any class wishing to process wxWindows events must use this macro
101 // This is the handler for process termination events
102 class MyProcess
: public wxProcess
105 MyProcess(MyFrame
*parent
, const wxString
& cmd
)
106 : wxProcess(parent
), m_cmd(cmd
)
111 // instead of overriding this virtual function we might as well process the
112 // event from it in the frame class - this might be more convenient in some
114 virtual void OnTerminate(int pid
, int status
);
121 // A specialization of MyProcess for redirecting the output
122 class MyPipedProcess
: public MyProcess
125 MyPipedProcess(MyFrame
*parent
, const wxString
& cmd
)
126 : MyProcess(parent
, cmd
)
131 virtual void OnTerminate(int pid
, int status
);
134 // ----------------------------------------------------------------------------
136 // ----------------------------------------------------------------------------
138 // IDs for the controls and the menu commands
152 static const wxChar
*DIALOG_TITLE
= _T("Exec sample");
154 // ----------------------------------------------------------------------------
155 // event tables and other macros for wxWindows
156 // ----------------------------------------------------------------------------
158 // the event tables connect the wxWindows events with the functions (event
159 // handlers) which process them. It can be also done at run-time, but for the
160 // simple menu events like this the static method is much simpler.
161 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
162 EVT_MENU(Exec_Quit
, MyFrame
::OnQuit
)
163 EVT_MENU(Exec_ClearLog
, MyFrame
::OnClear
)
165 EVT_MENU(Exec_SyncExec
, MyFrame
::OnSyncExec
)
166 EVT_MENU(Exec_AsyncExec
, MyFrame
::OnAsyncExec
)
167 EVT_MENU(Exec_Shell
, MyFrame
::OnShell
)
168 EVT_MENU(Exec_Redirect
, MyFrame
::OnExecWithRedirect
)
169 EVT_MENU(Exec_DDEExec
, MyFrame
::OnDDEExec
)
171 EVT_MENU(Exec_About
, MyFrame
::OnAbout
)
174 // Create a new application object: this macro will allow wxWindows to create
175 // the application object during program execution (it's better than using a
176 // static object for many reasons) and also declares the accessor function
177 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
181 // ============================================================================
183 // ============================================================================
185 // ----------------------------------------------------------------------------
186 // the application class
187 // ----------------------------------------------------------------------------
189 // `Main program' equivalent: the program execution "starts" here
192 // Create the main application window
193 MyFrame
*frame
= new MyFrame(_T("Exec wxWindows sample"),
194 wxDefaultPosition
, wxSize(500, 140));
196 // Show it and tell the application that it's our main window
200 // success: wxApp::OnRun() will be called which will enter the main message
201 // loop and the application will run. If we returned FALSE here, the
202 // application would exit immediately.
206 // ----------------------------------------------------------------------------
208 // ----------------------------------------------------------------------------
211 MyFrame
::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
212 : wxFrame((wxFrame
*)NULL
, -1, title
, pos
, size
)
215 // we need this in order to allow the about menu relocation, since ABOUT is
216 // not the default id of the about menu
217 wxApp
::s_macAboutMenuItemId
= Exec_About
;
220 // set the frame icon
222 SetIcon(wxICON(mondrian
));
226 wxMenu
*menuFile
= new wxMenu(_T(""), wxMENU_TEAROFF
);
227 menuFile
->Append(Exec_ClearLog
, _T("&Clear log\tCtrl-C"),
228 _T("Clear the log window"));
229 menuFile
->AppendSeparator();
230 menuFile
->Append(Exec_Quit
, _T("E&xit\tAlt-X"), _T("Quit this program"));
232 wxMenu
*execMenu
= new wxMenu
;
233 execMenu
->Append(Exec_SyncExec
, _T("Sync &execution...\tCtrl-E"),
234 _T("Launch a program and return when it terminates"));
235 execMenu
->Append(Exec_AsyncExec
, _T("&Async execution...\tCtrl-A"),
236 _T("Launch a program and return immediately"));
237 execMenu
->Append(Exec_Shell
, _T("Execute &shell command...\tCtrl-S"),
238 _T("Launch a shell and execute a command in it"));
239 execMenu
->Append(Exec_Redirect
, _T("Capture command &output...\tCtrl-O"),
240 _T("Launch a program and capture its output"));
243 execMenu
->AppendSeparator();
244 execMenu
->Append(Exec_DDEExec
, _T("Execute command via &DDE...\tCtrl-D"));
247 wxMenu
*helpMenu
= new wxMenu(_T(""), wxMENU_TEAROFF
);
248 helpMenu
->Append(Exec_About
, _T("&About...\tF1"), _T("Show about dialog"));
250 // now append the freshly created menu to the menu bar...
251 wxMenuBar
*menuBar
= new wxMenuBar();
252 menuBar
->Append(menuFile
, _T("&File"));
253 menuBar
->Append(execMenu
, _T("&Exec"));
254 menuBar
->Append(helpMenu
, _T("&Help"));
256 // ... and attach this menu bar to the frame
259 // create the listbox in which we will show misc messages as they come
260 m_lbox
= new wxListBox(this, -1);
263 // create a status bar just for fun (by default with 1 pane only)
265 SetStatusText(_T("Welcome to wxWindows exec sample!"));
266 #endif // wxUSE_STATUSBAR
272 void MyFrame
::OnQuit(wxCommandEvent
& WXUNUSED(event
))
274 // TRUE is to force the frame to close
278 void MyFrame
::OnClear(wxCommandEvent
& WXUNUSED(event
))
283 void MyFrame
::OnAbout(wxCommandEvent
& WXUNUSED(event
))
285 wxMessageBox(_T("Exec sample\n© 2000 Vadim Zeitlin"),
286 _T("About Exec"), wxOK
| wxICON_INFORMATION
, this);
289 void MyFrame
::OnSyncExec(wxCommandEvent
& WXUNUSED(event
))
291 wxString cmd
= wxGetTextFromUser(_T("Enter the command: "),
298 int code
= wxExecute(cmd
, TRUE
/* sync */);
299 wxLogStatus(_T("Process '%s' terminated with exit code %d."),
304 void MyFrame
::OnAsyncExec(wxCommandEvent
& WXUNUSED(event
))
306 wxString cmd
= wxGetTextFromUser(_T("Enter the command: "),
313 wxProcess
*process
= new MyProcess(this, cmd
);
314 if ( !wxExecute(cmd
, FALSE
/* async */, process
) )
316 wxLogError(_T("Execution of '%s' failed."), cmd
.c_str());
326 void MyFrame
::OnShell(wxCommandEvent
& WXUNUSED(event
))
328 wxString cmd
= wxGetTextFromUser(_T("Enter the command: "),
335 int code
= wxShell(cmd
);
336 wxLogStatus(_T("Shell command '%s' terminated with exit code %d."),
341 void MyFrame
::OnExecWithRedirect(wxCommandEvent
& WXUNUSED(event
))
343 wxString cmd
= wxGetTextFromUser(_T("Enter the command: "),
350 wxProcess
*process
= new MyPipedProcess(this, cmd
);
351 if ( !wxExecute(cmd
, FALSE
/* async */, process
) )
353 wxLogError(_T("Execution of '%s' failed."), cmd
.c_str());
363 void MyFrame
::OnDDEExec(wxCommandEvent
& WXUNUSED(event
))
366 wxString server
= wxGetTextFromUser(_T("Server to connect to:"),
367 DIALOG_TITLE
, _T("IExplore"));
371 wxString topic
= wxGetTextFromUser(_T("DDE topic:"),
372 DIALOG_TITLE
, _T("WWW_OpenURL"));
376 wxString cmd
= wxGetTextFromUser(_T("DDE command:"),
378 _T("\"file:F:\\wxWindows\\samples\\"
379 "image\\horse.gif\",,-1,,,,,"));
384 wxConnectionBase
*conn
= client
.MakeConnection("", server
, topic
);
387 wxLogError(_T("Failed to connect to the DDE server '%s'."),
392 if ( !conn
->Execute(cmd
) )
394 wxLogError(_T("Failed to execute command '%s' via DDE."),
399 wxLogStatus(_T("Successfully executed DDE command"));
402 #endif // __WINDOWS__
405 // ----------------------------------------------------------------------------
407 // ----------------------------------------------------------------------------
409 void MyProcess
::OnTerminate(int pid
, int status
)
411 wxLogStatus(m_parent
, _T("Process %u ('%s') terminated with exit code %d."),
412 pid
, m_cmd
.c_str(), status
);
414 // we're not needed any more
418 void MyPipedProcess
::OnTerminate(int pid
, int status
)
420 // show the program output
421 wxListBox
*lbox
= m_parent
->GetLogListBox();
422 lbox
->Append(wxString
::Format(_T("--- Output of '%s' ---"), m_cmd
.c_str()));
424 wxTextInputStream
tis(*m_in_stream
);
425 while ( !m_in_stream
->LastError() )
427 lbox
->Append(tis
.ReadLine());
430 MyProcess
::OnTerminate(pid
, status
);