]> git.saurik.com Git - wxWidgets.git/blob - src/msw/utilsexc.cpp
c9ef40cab63033033830f865fc8806810a50506c
[wxWidgets.git] / src / msw / utilsexc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utilsexec.cpp
3 // Purpose: Various utilities
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/setup.h"
25 #include "wx/utils.h"
26 #include "wx/app.h"
27 #include "wx/intl.h"
28 #endif
29
30 #include "wx/log.h"
31 #include "wx/process.h"
32
33 #include "wx/msw/private.h"
34
35 #include <windows.h>
36
37 #include <ctype.h>
38
39 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__)
40 #include <direct.h>
41 #ifndef __MWERKS__
42 #include <dos.h>
43 #endif
44 #endif
45
46 #ifdef __GNUWIN32__
47 #ifndef __TWIN32__
48 #include <sys/unistd.h>
49 #include <sys/stat.h>
50 #endif
51 #endif
52
53 #ifdef __WIN32__
54 #include <io.h>
55
56 #ifndef __GNUWIN32__
57 #include <shellapi.h>
58 #endif
59 #endif
60
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #ifndef __WATCOMC__
65 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
66 #include <errno.h>
67 #endif
68 #endif
69 #include <stdarg.h>
70
71 #define wxEXECUTE_WIN_MESSAGE 10000
72
73 struct wxExecuteData {
74 HWND window;
75 HINSTANCE process;
76 wxProcess *handler;
77 char state;
78 };
79
80
81 #ifdef __WIN32__
82 static DWORD wxExecuteThread(wxExecuteData *data)
83 {
84 WaitForSingleObject(data->process, INFINITE);
85
86 // Send an implicit message to the window
87 SendMessage(data->window, wxEXECUTE_WIN_MESSAGE, 0, (LPARAM)data);
88
89 return 0;
90 }
91 #endif
92
93
94 LRESULT APIENTRY _EXPORT wxExecuteWindowCbk(HWND hWnd, UINT message,
95 WPARAM wParam, LPARAM lParam)
96 {
97 wxExecuteData *data = (wxExecuteData *)lParam;
98
99 if (message == wxEXECUTE_WIN_MESSAGE) {
100 DestroyWindow(hWnd);
101 if (data->handler)
102 data->handler->OnTerminate((int)data->process, -1);
103
104 if (data->state)
105 data->state = 0;
106 else
107 delete data;
108 }
109 return 0;
110 }
111
112 extern char wxPanelClassName[];
113
114 long wxExecute(const wxString& command, bool sync, wxProcess *handler)
115 {
116 if (command == "")
117 return 0;
118
119 #if defined(__WIN32__) && !defined(__TWIN32__)
120 char * cl;
121 char * argp;
122 int clen;
123 HINSTANCE result;
124 DWORD dresult;
125 HWND window;
126 wxExecuteData *data;
127 DWORD tid;
128
129 // copy the command line
130 clen = command.Length();
131 if (!clen) return -1;
132 cl = (char *) calloc( 1, 256);
133 if (!cl) return -1;
134 strcpy( cl, WXSTRINGCAST command);
135
136 // isolate command and arguments
137 argp = strchr( cl, ' ');
138 if (argp)
139 *argp++ = '\0';
140
141 #ifdef __GNUWIN32__
142 result = ShellExecute((HWND) (wxTheApp->GetTopWindow() ? (HWND) wxTheApp->GetTopWindow()->GetHWND() : NULL),
143 (const wchar_t) "open", (const wchar_t) cl, (const wchar_t) argp,
144 (const wchar_t) NULL, SW_SHOWNORMAL);
145 #else
146 result = ShellExecute( (HWND) (wxTheApp->GetTopWindow() ? wxTheApp->GetTopWindow()->GetHWND() : NULL),
147 "open", cl, argp, NULL, SW_SHOWNORMAL);
148 #endif
149
150 if (((long)result) <= 32) {
151 free(cl);
152
153 wxLogSysError(_("Can't execute command '%s'"), command.c_str());
154 return 0;
155 }
156
157 // Alloc data
158 data = new wxExecuteData;
159
160 // Create window
161 window = CreateWindow(wxPanelClassName, NULL, 0, 0, 0, 0, 0, NULL,
162 (HMENU) NULL, wxGetInstance(), 0);
163
164 FARPROC ExecuteWindowInstance = MakeProcInstance((FARPROC) wxExecuteWindowCbk,
165 wxGetInstance());
166
167 SetWindowLong(window, GWL_WNDPROC, (LONG) ExecuteWindowInstance);
168 SetWindowLong(window, GWL_USERDATA, (LONG) data);
169
170 data->process = result;
171 data->window = window;
172 data->state = sync;
173 data->handler = (sync) ? NULL : handler;
174
175 dresult = (DWORD)CreateThread(NULL, 0,
176 (LPTHREAD_START_ROUTINE)wxExecuteThread,
177 (void *)data, 0, &tid);
178 if (dresult == 0) {
179 wxDebugMsg("wxExecute PANIC: I can't create the waiting thread !");
180 DestroyWindow(window);
181 return (long)result;
182 }
183
184 if (!sync)
185 {
186 free(cl);
187 return (long)result;
188 }
189
190 // waiting until command executed
191 while (data->state)
192 wxYield();
193
194 free(cl);
195 return 0;
196 #else
197 long instanceID = WinExec((LPCSTR) WXSTRINGCAST command, SW_SHOW);
198 if (instanceID < 32) return(0);
199
200 if (sync) {
201 int running;
202 do {
203 wxYield();
204 running = GetModuleUsage((HANDLE)instanceID);
205 } while (running);
206 }
207 return(instanceID);
208 #endif
209 }
210
211 long wxExecute(char **argv, bool sync, wxProcess *handler)
212 {
213 wxString command = "";
214
215 while (*argv != NULL) {
216 command += *argv;
217 command += ' ';
218 argv++;
219 }
220 command.RemoveLast();
221 return wxExecute(command, sync, handler);
222 }