/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/msw/main.cpp
ViewVC logotype

Contents of /trunk/3rdparty/wxWidgets/src/msw/main.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 4 months ago) by william
File size: 11960 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug in ./trunk
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/main.cpp
3 // Purpose: WinMain/DllMain
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id: main.cpp 44727 2007-03-10 17:24:09Z VZ $
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include "wx/event.h"
29 #include "wx/app.h"
30 #include "wx/utils.h"
31 #endif //WX_PRECOMP
32
33 #include "wx/cmdline.h"
34 #include "wx/scopeguard.h"
35
36 #include "wx/msw/private.h"
37 #include "wx/msw/seh.h"
38
39 #if wxUSE_ON_FATAL_EXCEPTION
40 #include "wx/datetime.h"
41 #include "wx/msw/crashrpt.h"
42 #endif // wxUSE_ON_FATAL_EXCEPTION
43
44 #ifdef __WXWINCE__
45 // there is no ExitProcess() under CE but exiting the main thread has the
46 // same effect
47 #ifndef ExitProcess
48 #define ExitProcess ExitThread
49 #endif
50 #endif // __WXWINCE__
51
52 #ifdef __BORLANDC__
53 // BC++ has to be special: its run-time expects the DLL entry point to be
54 // named DllEntryPoint instead of the (more) standard DllMain
55 #define DllMain DllEntryPoint
56 #endif // __BORLANDC__
57
58 #if defined(__WXMICROWIN__)
59 #define HINSTANCE HANDLE
60 #endif
61
62 // defined in common/init.cpp
63 extern int wxEntryReal(int& argc, wxChar **argv);
64
65 // ============================================================================
66 // implementation: various entry points
67 // ============================================================================
68
69 #if wxUSE_BASE
70
71 #if wxUSE_ON_FATAL_EXCEPTION && defined(__VISUALC__) && !defined(__WXWINCE__)
72 // VC++ (at least from 4.0 up to version 7.1) is incredibly broken in that
73 // a "catch ( ... )" will *always* catch SEH exceptions in it even though
74 // it should have never been the case... to prevent such catches from
75 // stealing the exceptions from our wxGlobalSEHandler which is only called
76 // if the exception is not handled elsewhere, we have to also call it from
77 // a special SEH translator function which is called by VC CRT when a Win32
78 // exception occurs
79
80 // this warns that /EHa (async exceptions) should be used when using
81 // _set_se_translator but, in fact, this doesn't seem to change anything
82 // with VC++ up to 8.0
83 #if _MSC_VER <= 1400
84 #pragma warning(disable:4535)
85 #endif
86
87 // note that the SE translator must be called wxSETranslator!
88 #define DisableAutomaticSETranslator() _set_se_translator(wxSETranslator)
89 #else // !__VISUALC__
90 #define DisableAutomaticSETranslator()
91 #endif // __VISUALC__/!__VISUALC__
92
93 // ----------------------------------------------------------------------------
94 // wrapper wxEntry catching all Win32 exceptions occurring in a wx program
95 // ----------------------------------------------------------------------------
96
97 // wrap real wxEntry in a try-except block to be able to call
98 // OnFatalException() if necessary
99 #if wxUSE_ON_FATAL_EXCEPTION
100
101 // global pointer to exception information, only valid inside OnFatalException,
102 // used by wxStackWalker and wxCrashReport
103 EXCEPTION_POINTERS *wxGlobalSEInformation = NULL;
104
105 // flag telling us whether the application wants to handle exceptions at all
106 static bool gs_handleExceptions = false;
107
108 static void wxFatalExit()
109 {
110 // use the same exit code as abort()
111 ::ExitProcess(3);
112 }
113
114 unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs)
115 {
116 if ( gs_handleExceptions && wxTheApp )
117 {
118 // store the pointer to exception info
119 wxGlobalSEInformation = pExcPtrs;
120
121 // give the user a chance to do something special about this
122 wxSEH_TRY
123 {
124 wxTheApp->OnFatalException();
125 }
126 wxSEH_IGNORE // ignore any exceptions inside the exception handler
127
128 wxGlobalSEInformation = NULL;
129
130 // this will execute our handler and terminate the process
131 return EXCEPTION_EXECUTE_HANDLER;
132 }
133
134 return EXCEPTION_CONTINUE_SEARCH;
135 }
136
137 #ifdef __VISUALC__
138
139 void wxSETranslator(unsigned int WXUNUSED(code), EXCEPTION_POINTERS *ep)
140 {
141 switch ( wxGlobalSEHandler(ep) )
142 {
143 default:
144 wxFAIL_MSG( _T("unexpected wxGlobalSEHandler() return value") );
145 // fall through
146
147 case EXCEPTION_EXECUTE_HANDLER:
148 // if wxApp::OnFatalException() had been called we should exit the
149 // application -- but we shouldn't kill our host when we're a DLL
150 #ifndef WXMAKINGDLL
151 wxFatalExit();
152 #endif // not a DLL
153 break;
154
155 case EXCEPTION_CONTINUE_SEARCH:
156 // we're called for each "catch ( ... )" and if we (re)throw from
157 // here, the catch handler body is not executed, so the effect is
158 // as if had inhibited translation of SE to C++ ones because the
159 // handler will never see any structured exceptions
160 throw;
161 }
162 }
163
164 #endif // __VISUALC__
165
166 bool wxHandleFatalExceptions(bool doit)
167 {
168 // assume this can only be called from the main thread
169 gs_handleExceptions = doit;
170
171 #if wxUSE_CRASHREPORT
172 if ( doit )
173 {
174 // try to find a place where we can put out report file later
175 wxChar fullname[MAX_PATH];
176 if ( !::GetTempPath(WXSIZEOF(fullname), fullname) )
177 {
178 wxLogLastError(_T("GetTempPath"));
179
180 // when all else fails...
181 wxStrcpy(fullname, _T("c:\\"));
182 }
183
184 // use PID and date to make the report file name more unique
185 wxString name = wxString::Format
186 (
187 _T("%s_%s_%lu.dmp"),
188 wxTheApp ? wxTheApp->GetAppName().c_str()
189 : _T("wxwindows"),
190 wxDateTime::Now().Format(_T("%Y%m%dT%H%M%S")).c_str(),
191 ::GetCurrentProcessId()
192 );
193
194 wxStrncat(fullname, name, WXSIZEOF(fullname) - wxStrlen(fullname) - 1);
195
196 wxCrashReport::SetFileName(fullname);
197 }
198 #endif // wxUSE_CRASHREPORT
199
200 return true;
201 }
202
203 int wxEntry(int& argc, wxChar **argv)
204 {
205 DisableAutomaticSETranslator();
206
207 wxSEH_TRY
208 {
209 return wxEntryReal(argc, argv);
210 }
211 wxSEH_HANDLE(-1)
212 }
213
214 // PCSX2: Moved this to inside the wxUSE_ON_FATAL_EXCEPTION condition --air
215 #if defined(__VISUALC__) && !defined(__WXWINCE__)
216
217 static void
218 wxSETranslator(unsigned int WXUNUSED(code), EXCEPTION_POINTERS * WXUNUSED(ep))
219 {
220 // see wxSETranslator() version for wxUSE_ON_FATAL_EXCEPTION above
221 throw;
222 }
223
224 #endif // __VISUALC__
225
226 #else // !wxUSE_ON_FATAL_EXCEPTION
227
228 int wxEntry(int& argc, wxChar **argv)
229 {
230 DisableAutomaticSETranslator();
231
232 return wxEntryReal(argc, argv);
233 }
234
235 #endif // wxUSE_ON_FATAL_EXCEPTION/!wxUSE_ON_FATAL_EXCEPTION
236
237 #endif // wxUSE_BASE
238
239 #if wxUSE_GUI && defined(__WXMSW__)
240
241 #if wxUSE_UNICODE && !defined(__WXWINCE__)
242 #define NEED_UNICODE_CHECK
243 #endif
244
245 #ifdef NEED_UNICODE_CHECK
246
247 // check whether Unicode is available
248 static bool wxIsUnicodeAvailable()
249 {
250 static const wchar_t *ERROR_STRING = L"wxWidgets Fatal Error";
251
252 if ( wxGetOsVersion() != wxOS_WINDOWS_NT )
253 {
254 // we need to be built with MSLU support
255 #if !wxUSE_UNICODE_MSLU
256 // note that we can use MessageBoxW() as it's implemented even under
257 // Win9x - OTOH, we can't use wxGetTranslation() because the file APIs
258 // used by wxLocale are not
259 ::MessageBox
260 (
261 NULL,
262 L"This program uses Unicode and requires Windows NT/2000/XP.\n"
263 L"\n"
264 L"Program aborted.",
265 ERROR_STRING,
266 MB_ICONERROR | MB_OK
267 );
268
269 return false;
270 #else // wxUSE_UNICODE_MSLU
271 // and the MSLU DLL must also be available
272 HMODULE hmod = ::LoadLibraryA("unicows.dll");
273 if ( !hmod )
274 {
275 ::MessageBox
276 (
277 NULL,
278 L"This program uses Unicode and requires unicows.dll to work "
279 L"under current operating system.\n"
280 L"\n"
281 L"Please install unicows.dll and relaunch the program.",
282 ERROR_STRING,
283 MB_ICONERROR | MB_OK
284 );
285 return false;
286 }
287
288 // this is not really necessary but be tidy
289 ::FreeLibrary(hmod);
290
291 // finally do the last check: has unicows.lib initialized correctly?
292 hmod = ::LoadLibraryW(L"unicows.dll");
293 if ( !hmod )
294 {
295 ::MessageBox
296 (
297 NULL,
298 L"This program uses Unicode but is not using unicows.dll\n"
299 L"correctly and so cannot work under current operating system.\n"
300 L"Please contact the program author for an updated version.\n"
301 L"\n"
302 L"Program aborted.",
303 ERROR_STRING,
304 MB_ICONERROR | MB_OK
305 );
306
307 return false;
308 }
309
310 ::FreeLibrary(hmod);
311 #endif // !wxUSE_UNICODE_MSLU
312 }
313
314 return true;
315 }
316
317 #endif // NEED_UNICODE_CHECK
318
319 // ----------------------------------------------------------------------------
320 // Windows-specific wxEntry
321 // ----------------------------------------------------------------------------
322
323 // helper function used to clean up in wxEntry() just below
324 //
325 // notice that argv elements are supposed to be allocated using malloc() while
326 // argv array itself is allocated with new
327 static void wxFreeArgs(int argc, wxChar **argv)
328 {
329 for ( int i = 0; i < argc; i++ )
330 {
331 free(argv[i]);
332 }
333
334 delete [] argv;
335 }
336
337 WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
338 HINSTANCE WXUNUSED(hPrevInstance),
339 wxCmdLineArgType WXUNUSED(pCmdLine),
340 int nCmdShow)
341 {
342 // the first thing to do is to check if we're trying to run an Unicode
343 // program under Win9x w/o MSLU emulation layer - if so, abort right now
344 // as it has no chance to work and has all chances to crash
345 #ifdef NEED_UNICODE_CHECK
346 if ( !wxIsUnicodeAvailable() )
347 return -1;
348 #endif // NEED_UNICODE_CHECK
349
350
351 // remember the parameters Windows gave us
352 wxSetInstance(hInstance);
353 wxApp::m_nCmdShow = nCmdShow;
354
355 // parse the command line: we can't use pCmdLine in Unicode build so it is
356 // simpler to never use it at all (this also results in a more correct
357 // argv[0])
358
359 // break the command line in words
360 wxArrayString args;
361
362 const wxChar *cmdLine = ::GetCommandLine();
363 if ( cmdLine )
364 {
365 args = wxCmdLineParser::ConvertStringToArgs(cmdLine);
366 }
367
368 #ifdef __WXWINCE__
369 // WinCE doesn't insert the program itself, so do it ourselves.
370 args.Insert(wxGetFullModuleName(), 0);
371 #endif
372
373 int argc = args.GetCount();
374
375 // +1 here for the terminating NULL
376 wxChar **argv = new wxChar *[argc + 1];
377 for ( int i = 0; i < argc; i++ )
378 {
379 argv[i] = wxStrdup(args[i]);
380 }
381
382 // argv[] must be NULL-terminated
383 argv[argc] = NULL;
384
385 wxON_BLOCK_EXIT2(wxFreeArgs, argc, argv);
386
387 return wxEntry(argc, argv);
388 }
389
390 #endif // wxUSE_GUI && __WXMSW__
391
392 // ----------------------------------------------------------------------------
393 // global HINSTANCE
394 // ----------------------------------------------------------------------------
395
396 #if wxUSE_BASE
397
398 HINSTANCE wxhInstance = 0;
399
400 extern "C" HINSTANCE wxGetInstance()
401 {
402 return wxhInstance;
403 }
404
405 void wxSetInstance(HINSTANCE hInst)
406 {
407 wxhInstance = hInst;
408 }
409
410 #endif // wxUSE_BASE

  ViewVC Help
Powered by ViewVC 1.1.22