]> git.saurik.com Git - wxWidgets.git/blame - src/os2/utilsexc.cpp
attempt to fix wxMenuBar::EnableTop
[wxWidgets.git] / src / os2 / utilsexc.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: utilsexec.cpp
d90895ac
DW
3// Purpose: Various utilities
4// Author: David Webster
0e320a79 5// Modified by:
d90895ac 6// Created: 10/17/99
0e320a79 7// RCS-ID: $Id$
d90895ac
DW
8// Copyright: (c) David Webster
9// Licence: wxWindows license
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
d90895ac
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
0e320a79 14
d90895ac
DW
15#ifndef WX_PRECOMP
16#include "wx/setup.h"
0e320a79 17#include "wx/utils.h"
d90895ac
DW
18#include "wx/app.h"
19#include "wx/intl.h"
20#endif
21
22#include "wx/log.h"
23
24#include "wx/process.h"
25
26#include "wx/os2/private.h"
27
28#define INCL_DOS
29#include <os2.h>
30
31#include <ctype.h>
32#include <direct.h>
33
34#include <sys/stat.h>
35#include <io.h>
0e320a79
DW
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
d90895ac
DW
40#include <errno.h>
41#include <stdarg.h>
42
43// this message is sent when the process we're waiting for terminates
44#define wxWM_PROC_TERMINATED (WM_USER + 10000)
45
46// structure describing the process we're being waiting for
47struct wxExecuteData
48{
49public:
50 ~wxExecuteData()
51 {
52// TODO:
53/*
54 if ( !::CloseHandle(hProcess) )
55 {
56 wxLogLastError("CloseHandle(hProcess)");
57 }
58*/
59 }
60
61 HWND hWnd; // window to send wxWM_PROC_TERMINATED to
62 HANDLE hProcess; // handle of the process
63 DWORD dwProcessId; // pid of the process
64 wxProcess *handler;
65 DWORD dwExitCode; // the exit code of the process
66 bool state; // set to FALSE when the process finishes
67};
68
69
70static DWORD wxExecuteThread(wxExecuteData *data)
71{
72// TODO:
73/*
74 WaitForSingleObject(data->hProcess, INFINITE);
0e320a79 75
d90895ac
DW
76 // get the exit code
77 if ( !GetExitCodeProcess(data->hProcess, &data->dwExitCode) )
78 {
79 wxLogLastError("GetExitCodeProcess");
80 }
81
82 wxASSERT_MSG( data->dwExitCode != STILL_ACTIVE,
83 wxT("process should have terminated") );
84
85 // send a message indicating process termination to the window
86 SendMessage(data->hWnd, wxWM_PROC_TERMINATED, 0, (LPARAM)data);
87*/
88 return 0;
89}
90
91// window procedure of a hidden window which is created just to receive
92// the notification message when a process exits
93MRESULT APIENTRY wxExecuteWindowCbk(HWND hWnd, UINT message,
94 MPARAM wParam, MPARAM lParam)
95{
96 if ( message == wxWM_PROC_TERMINATED )
97 {
98// DestroyWindow(hWnd); // we don't need it any more
99
100 wxExecuteData *data = (wxExecuteData *)lParam;
101 if ( data->handler )
102 {
103 data->handler->OnTerminate((int)data->dwProcessId,
104 (int)data->dwExitCode);
105 }
106
107 if ( data->state )
108 {
109 // we're executing synchronously, tell the waiting thread
110 // that the process finished
111 data->state = 0;
112 }
113 else
114 {
115 // asynchronous execution - we should do the clean up
116 delete data;
117 }
118 }
119
120 return 0;
121}
122
123extern wxChar wxPanelClassName[];
0e320a79
DW
124
125long wxExecute(const wxString& command, bool sync, wxProcess *handler)
126{
d90895ac
DW
127 wxCHECK_MSG( !!command, 0, wxT("empty command in wxExecute") );
128
129 // the old code is disabled because we really need a process handle
130 // if we want to execute it asynchronously or even just get its
131 // return code and for this we must use CreateProcess() and not
132 // ShellExecute()
133
134 // create the process
135// TODO:
136/*
137 STARTUPINFO si;
138 memset(&si, 0, sizeof(si));
139 si.cb = sizeof(si);
140
141 PROCESS_INFORMATION pi;
142
143 if ( ::CreateProcess(
144 NULL, // application name (use only cmd line)
145 (wxChar *)command.c_str(), // full command line
146 NULL, // security attributes: defaults for both
147 NULL, // the process and its main thread
148 FALSE, // don't inherit handles
149 CREATE_DEFAULT_ERROR_MODE, // flags
150 NULL, // environment (use the same)
151 NULL, // current directory (use the same)
152 &si, // startup info (unused here)
153 &pi // process info
154 ) == 0 )
155 {
156 wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
157
158 return 0;
159 }
160
161 // close unneeded handle
162 if ( !::CloseHandle(pi.hThread) )
163 wxLogLastError("CloseHandle(hThread)");
164
165 // create a hidden window to receive notification about process
166 // termination
167 HWND hwnd = ::CreateWindow(wxPanelClassName, NULL, 0, 0, 0, 0, 0, NULL,
168 (HMENU)NULL, wxGetInstance(), 0);
169 wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
170
171 FARPROC ExecuteWindowInstance = MakeProcInstance((FARPROC)wxExecuteWindowCbk,
172 wxGetInstance());
173
174 ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) ExecuteWindowInstance);
175
176 // Alloc data
177 wxExecuteData *data = new wxExecuteData;
178 data->hProcess = pi.hProcess;
179 data->dwProcessId = pi.dwProcessId;
180 data->hWnd = hwnd;
181 data->state = sync;
182 if ( sync )
183 {
184 wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") );
185
186 data->handler = NULL;
187 }
188 else
189 {
190 // may be NULL or not
191 data->handler = handler;
192 }
193
194 DWORD tid;
195 HANDLE hThread = ::CreateThread(NULL,
196 0,
197 (LPTHREAD_START_ROUTINE)wxExecuteThread,
198 (void *)data,
199 0,
200 &tid);
201
202 if ( !hThread )
203 {
204 wxLogLastError("CreateThread in wxExecute");
205
206 DestroyWindow(hwnd);
207 delete data;
208
209 // the process still started up successfully...
210 return pi.dwProcessId;
211 }
212
213 if ( !sync )
214 {
215 // clean up will be done when the process terminates
216
217 // return the pid
218 return pi.dwProcessId;
219 }
220
221 // waiting until command executed
222 while ( data->state )
223 wxYield();
224
225 DWORD dwExitCode = data->dwExitCode;
226 delete data;
227
228 // return the exit code
229 return dwExitCode;
230*/
0e320a79
DW
231 return 0;
232}
d90895ac
DW
233
234long wxExecute(char **argv, bool sync, wxProcess *handler)
235{
236 wxString command;
237
238 while ( *argv != NULL )
239 {
240 command << *argv++ << ' ';
241 }
242
243 command.RemoveLast();
244
245 return wxExecute(command, sync, handler);
246}
247
248bool wxGetFullHostName(wxChar *buf, int maxSize)
249{
250 DWORD nSize = maxSize ;
251// TODO:
252/*
253 if ( !::GetComputerName(buf, &nSize) )
254 {
255 wxLogLastError("GetComputerName");
256
257 return FALSE;
258 }
259*/
260 return TRUE;
261}
262