1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: WinMain/DllMain
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
33 #include "wx/cmdline.h"
35 #include "wx/msw/private.h"
37 #if wxUSE_ON_FATAL_EXCEPTION
38 #include "wx/datetime.h"
39 #include "wx/msw/crashrpt.h"
44 #endif // wxUSE_ON_FATAL_EXCEPTION
47 // there is no ExitProcess() under CE but exiting the main thread has the
50 #define ExitProcess ExitThread
55 // BC++ has to be special: its run-time expects the DLL entry point to be
56 // named DllEntryPoint instead of the (more) standard DllMain
57 #define DllMain DllEntryPoint
60 #if defined(__WXMICROWIN__)
61 #define HINSTANCE HANDLE
64 // ============================================================================
65 // implementation: various entry points
66 // ============================================================================
68 // ----------------------------------------------------------------------------
69 // wrapper wxEntry catching all Win32 exceptions occuring in a wx program
70 // ----------------------------------------------------------------------------
72 // wrap real wxEntry in a try-except block to be able to call
73 // OnFatalException() if necessary
74 #if wxUSE_ON_FATAL_EXCEPTION && wxUSE_BASE
76 // global pointer to exception information, only valid inside OnFatalException,
77 // used by wxStackWalker and wxCrashReport
78 extern EXCEPTION_POINTERS
*wxGlobalSEInformation
= NULL
;
80 // flag telling us whether the application wants to handle exceptions at all
81 static bool gs_handleExceptions
= false;
83 unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS
*pExcPtrs
)
85 if ( gs_handleExceptions
&& wxTheApp
)
87 // store the pointer to exception info
88 wxGlobalSEInformation
= pExcPtrs
;
90 // give the user a chance to do something special about this
93 wxTheApp
->OnFatalException();
95 __except ( EXCEPTION_EXECUTE_HANDLER
)
97 // nothing to do here, just ignore the exception inside the
102 wxGlobalSEInformation
= NULL
;
104 // this will execute our handler and terminate the process
105 return EXCEPTION_EXECUTE_HANDLER
;
108 return EXCEPTION_CONTINUE_SEARCH
;
113 static void wxSETranslator(unsigned int WXUNUSED(code
), EXCEPTION_POINTERS
*ep
)
115 wxGlobalSEHandler(ep
);
118 #endif // __VISUALC__
120 bool wxHandleFatalExceptions(bool doit
)
122 // assume this can only be called from the main thread
123 gs_handleExceptions
= doit
;
126 // VC++ (at least from 4.0 up to version 7.1) is incredibly broken in that
127 // a "catch ( ... )" will *always* catch SEH exceptions in it even though
128 // it should have never been the case... to prevent such catches from
129 // stealing the exceptions from our wxGlobalSEHandler which is only called
130 // if the exception is not handled elsewhere, we have to also call it from
131 // a special SEH translator function which is called by VC CRT when a Win32
134 // this warns that /EHa (async exceptions) should be used when using
135 // _set_se_translator but, in fact, this doesn't seem to change anything
136 // with VC++ up to 7.1 -- to be confirmed with VC++ 8
138 #pragma warning(disable:4535)
141 _set_se_translator(doit
? wxSETranslator
: NULL
);
144 #if wxUSE_CRASHREPORT
147 // try to find a place where we can put out report file later
148 wxChar fullname
[MAX_PATH
];
149 if ( !::GetTempPath(WXSIZEOF(fullname
), fullname
) )
151 wxLogLastError(_T("GetTempPath"));
153 // when all else fails...
154 wxStrcpy(fullname
, _T("c:\\"));
157 // use PID and date to make the report file name more unique
158 wxString name
= wxString::Format
161 wxTheApp
? wxTheApp
->GetAppName().c_str()
163 wxDateTime::Now().Format(_T("%Y%m%dT%H%M%S")).c_str(),
164 ::GetCurrentProcessId()
167 wxStrncat(fullname
, name
, WXSIZEOF(fullname
) - wxStrlen(fullname
) - 1);
169 wxCrashReport::SetFileName(fullname
);
171 #endif // wxUSE_CRASHREPORT
176 int wxEntry(int& argc
, wxChar
**argv
)
180 extern int wxEntryReal(int& argc
, wxChar
**argv
);
182 return wxEntryReal(argc
, argv
);
184 __except ( wxGlobalSEHandler(GetExceptionInformation()) )
186 ::ExitProcess(3); // the same exit code as abort()
188 #if !defined(_MSC_VER) || _MSC_VER < 1300
189 // this code is unreachable but put it here to suppress warnings
190 // from some compilers
196 #endif // wxUSE_ON_FATAL_EXCEPTION && wxUSE_BASE
200 // ----------------------------------------------------------------------------
201 // Windows-specific wxEntry
202 // ----------------------------------------------------------------------------
204 WXDLLEXPORT
int wxEntry(HINSTANCE hInstance
,
205 HINSTANCE
WXUNUSED(hPrevInstance
),
206 wxCmdLineArgType
WXUNUSED(pCmdLine
),
209 // remember the parameters Windows gave us
210 wxSetInstance(hInstance
);
211 wxApp::m_nCmdShow
= nCmdShow
;
213 // parse the command line: we can't use pCmdLine in Unicode build so it is
214 // simpler to never use it at all (this also results in a more correct
217 // break the command line in words
220 const wxChar
*cmdLine
= ::GetCommandLine();
223 args
= wxCmdLineParser::ConvertStringToArgs(cmdLine
);
227 // WinCE doesn't insert the program itself, so do it ourselves.
228 args
.Insert(wxGetFullModuleName(), 0);
231 int argc
= args
.GetCount();
233 // +1 here for the terminating NULL
234 wxChar
**argv
= new wxChar
*[argc
+ 1];
235 for ( int i
= 0; i
< argc
; i
++ )
237 argv
[i
] = wxStrdup(args
[i
]);
240 // argv[] must be NULL-terminated
243 return wxEntry(argc
, argv
);
246 // May wish not to have a DllMain or WinMain, e.g. if we're programming
247 // a Netscape plugin or if we're writing a console application
253 // ----------------------------------------------------------------------------
255 // ----------------------------------------------------------------------------
257 // Note that WinMain is also defined in dummy.obj, which is linked to
258 // an application that is using the DLL version of wxWidgets.
265 DllMain(HANDLE hModule
, DWORD fdwReason
, LPVOID
WXUNUSED(lpReserved
))
267 // Only call wxEntry if the application itself is part of the DLL.
268 // If only the wxWidgets library is in the DLL, then the
269 // initialisation will be called when the application implicitly
274 case DLL_PROCESS_ATTACH
:
275 return wxEntry(hModule
);
277 case DLL_PROCESS_DETACH
:
284 #endif // !WXMAKINGDLL
297 // ----------------------------------------------------------------------------
299 // ----------------------------------------------------------------------------
303 HINSTANCE wxhInstance
= 0;
305 extern "C" HINSTANCE
wxGetInstance()
310 void wxSetInstance(HINSTANCE hInst
)