]> git.saurik.com Git - wxWidgets.git/blame - src/msw/main.cpp
Add support for wxSL_INVERSE flag. Also uses new inverse logic to make Mac vertical...
[wxWidgets.git] / src / msw / main.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
b568d04f 2// Name: msw/main.cpp
e2478fde 3// Purpose: WinMain/DllMain
2bda0e17
KB
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
6c9a19aa 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
b568d04f
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
b568d04f 21 #pragma implementation
a3b46648
UU
22#endif
23
2bda0e17
KB
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
b568d04f 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
2432b92d 31#include "wx/event.h"
2bda0e17 32#include "wx/app.h"
94826170 33#include "wx/cmdline.h"
b568d04f
VZ
34
35#include "wx/msw/private.h"
36
8c125d13
VZ
37#if wxUSE_ON_FATAL_EXCEPTION
38 #include "wx/datetime.h"
39 #include "wx/msw/crashrpt.h"
40
41 #ifdef __VISUALC__
42 #include <eh.h>
43 #endif // __VISUALC__
44#endif // wxUSE_ON_FATAL_EXCEPTION
45
46#ifdef __WXWINCE__
47 // there is no ExitProcess() under CE but exiting the main thread has the
48 // same effect
49 #define ExitProcess ExitThread
50#endif
51
e2478fde
VZ
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
57
58#if defined(__WXMICROWIN__)
59 #define HINSTANCE HANDLE
60#endif
beed393c 61
b568d04f 62// ============================================================================
e2478fde 63// implementation: various entry points
b568d04f
VZ
64// ============================================================================
65
8c125d13
VZ
66// ----------------------------------------------------------------------------
67// wrapper wxEntry catching all Win32 exceptions occuring in a wx program
68// ----------------------------------------------------------------------------
69
70// wrap real wxEntry in a try-except block to be able to call
71// OnFatalException() if necessary
58187c86 72#if wxUSE_ON_FATAL_EXCEPTION && wxUSE_BASE
8c125d13
VZ
73
74// global pointer to exception information, only valid inside OnFatalException,
75// used by wxStackWalker and wxCrashReport
76extern EXCEPTION_POINTERS *wxGlobalSEInformation = NULL;
77
78// flag telling us whether the application wants to handle exceptions at all
79static bool gs_handleExceptions = false;
80
81unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs)
82{
83 if ( gs_handleExceptions && wxTheApp )
84 {
85 // store the pointer to exception info
86 wxGlobalSEInformation = pExcPtrs;
87
88 // give the user a chance to do something special about this
89 __try
90 {
91 wxTheApp->OnFatalException();
92 }
93 __except ( EXCEPTION_EXECUTE_HANDLER )
94 {
95 // nothing to do here, just ignore the exception inside the
96 // exception handler
97 ;
98 }
99
100 wxGlobalSEInformation = NULL;
101
102 // this will execute our handler and terminate the process
103 return EXCEPTION_EXECUTE_HANDLER;
104 }
105
106 return EXCEPTION_CONTINUE_SEARCH;
107}
108
109#ifdef __VISUALC__
110
111static void wxSETranslator(unsigned int WXUNUSED(code), EXCEPTION_POINTERS *ep)
112{
113 wxGlobalSEHandler(ep);
114}
115
116#endif // __VISUALC__
117
118bool wxHandleFatalExceptions(bool doit)
119{
120 // assume this can only be called from the main thread
121 gs_handleExceptions = doit;
122
123#ifdef __VISUALC__
124 // VC++ (at least from 4.0 up to version 7.1) is incredibly broken in that
125 // a "catch ( ... )" will *always* catch SEH exceptions in it even though
126 // it should have never been the case... to prevent such catches from
127 // stealing the exceptions from our wxGlobalSEHandler which is only called
128 // if the exception is not handled elsewhere, we have to also call it from
129 // a special SEH translator function which is called by VC CRT when a Win32
130 // exception occurs
b059b79d
VZ
131
132 // this warns that /EHa (async exceptions) should be used when using
133 // _set_se_translator but, in fact, this doesn't seem to change anything
134 // with VC++ up to 7.1 -- to be confirmed with VC++ 8
135 #if _MSC_VER <= 1310
136 #pragma warning(disable:4535)
137 #endif
138
8c125d13
VZ
139 _set_se_translator(doit ? wxSETranslator : NULL);
140#endif
141
142#if wxUSE_CRASHREPORT
143 if ( doit )
144 {
145 // try to find a place where we can put out report file later
146 wxChar fullname[MAX_PATH];
147 if ( !::GetTempPath(WXSIZEOF(fullname), fullname) )
148 {
149 wxLogLastError(_T("GetTempPath"));
150
151 // when all else fails...
152 wxStrcpy(fullname, _T("c:\\"));
153 }
154
155 // use PID and date to make the report file name more unique
156 wxString name = wxString::Format
157 (
158 _T("%s_%s_%lu.dmp"),
159 wxTheApp ? wxTheApp->GetAppName().c_str()
160 : _T("wxwindows"),
161 wxDateTime::Now().Format(_T("%Y%m%dT%H%M%S")).c_str(),
162 ::GetCurrentProcessId()
163 );
164
165 wxStrncat(fullname, name, WXSIZEOF(fullname) - wxStrlen(fullname) - 1);
166
167 wxCrashReport::SetFileName(fullname);
168 }
169#endif // wxUSE_CRASHREPORT
170
171 return true;
172}
173
174int wxEntry(int& argc, wxChar **argv)
175{
176 __try
177 {
178 extern int wxEntryReal(int& argc, wxChar **argv);
179
180 return wxEntryReal(argc, argv);
181 }
182 __except ( wxGlobalSEHandler(GetExceptionInformation()) )
183 {
184 ::ExitProcess(3); // the same exit code as abort()
185
186#if !defined(_MSC_VER) || _MSC_VER < 1300
187 // this code is unreachable but put it here to suppress warnings
188 // from some compilers
189 return -1;
190#endif
191 }
192}
193
58187c86 194#endif // wxUSE_ON_FATAL_EXCEPTION && wxUSE_BASE
8c125d13
VZ
195
196#if wxUSE_GUI
197
94826170
VZ
198// ----------------------------------------------------------------------------
199// Windows-specific wxEntry
200// ----------------------------------------------------------------------------
201
b5fe6924
VS
202WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
203 HINSTANCE WXUNUSED(hPrevInstance),
7c8c7cc2 204 wxCmdLineArgType WXUNUSED(pCmdLine),
b5fe6924 205 int nCmdShow)
94826170
VZ
206{
207 // remember the parameters Windows gave us
13bdd545 208 wxSetInstance(hInstance);
94826170
VZ
209 wxApp::m_nCmdShow = nCmdShow;
210
b2b1371c
VZ
211 // parse the command line: we can't use pCmdLine in Unicode build so it is
212 // simpler to never use it at all (this also results in a more correct
213 // argv[0])
214
215 // break the command line in words
216 wxArrayString args;
13a5a49f 217
b2b1371c
VZ
218 const wxChar *cmdLine = ::GetCommandLine();
219 if ( cmdLine )
220 {
221 args = wxCmdLineParser::ConvertStringToArgs(cmdLine);
222 }
223
13a5a49f 224#ifdef __WXWINCE__
77d8d6cd
VZ
225 // WinCE doesn't insert the program itself, so do it ourselves.
226 args.Insert(wxGetFullModuleName(), 0);
13a5a49f
JS
227#endif
228
b2b1371c
VZ
229 int argc = args.GetCount();
230
231 // +1 here for the terminating NULL
232 wxChar **argv = new wxChar *[argc + 1];
233 for ( int i = 0; i < argc; i++ )
234 {
235 argv[i] = wxStrdup(args[i]);
236 }
237
238 // argv[] must be NULL-terminated
239 argv[argc] = NULL;
94826170
VZ
240
241 return wxEntry(argc, argv);
242}
243
2bda0e17 244// May wish not to have a DllMain or WinMain, e.g. if we're programming
b568d04f 245// a Netscape plugin or if we're writing a console application
94826170 246#if !defined(NOMAIN)
2bda0e17 247
e2478fde
VZ
248extern "C"
249{
2bda0e17 250
e2478fde 251// ----------------------------------------------------------------------------
2bda0e17 252// WinMain
e2478fde
VZ
253// ----------------------------------------------------------------------------
254
2bda0e17 255// Note that WinMain is also defined in dummy.obj, which is linked to
77ffb593 256// an application that is using the DLL version of wxWidgets.
2bda0e17 257
ac9a3c61 258#if defined(_WINDLL)
2bda0e17
KB
259
260// DLL entry point
261
e2478fde
VZ
262BOOL WINAPI
263DllMain(HANDLE hModule, DWORD fdwReason, LPVOID WXUNUSED(lpReserved))
2bda0e17 264{
e2478fde 265 // Only call wxEntry if the application itself is part of the DLL.
77ffb593 266 // If only the wxWidgets library is in the DLL, then the
e2478fde
VZ
267 // initialisation will be called when the application implicitly
268 // calls WinMain.
beed393c 269#ifndef WXMAKINGDLL
2bda0e17 270 switch (fdwReason)
b568d04f
VZ
271 {
272 case DLL_PROCESS_ATTACH:
13bdd545 273 return wxEntry(hModule);
2bda0e17 274
b568d04f 275 case DLL_PROCESS_DETACH:
94826170
VZ
276 wxEntryCleanup();
277 break;
b568d04f 278 }
33ac7e6f 279#else
598ddd96
WS
280 (void)hModule;
281 (void)fdwReason;
beed393c 282#endif // !WXMAKINGDLL
e2478fde 283
b568d04f 284 return TRUE;
2bda0e17
KB
285}
286
ac9a3c61 287#endif // _WINDLL
e2478fde
VZ
288
289} // extern "C"
2bda0e17 290
b568d04f
VZ
291#endif // !NOMAIN
292
94826170
VZ
293#endif // wxUSE_GUI
294
b568d04f 295// ----------------------------------------------------------------------------
e2478fde 296// global HINSTANCE
b568d04f
VZ
297// ----------------------------------------------------------------------------
298
ec67cff1 299#if wxUSE_BASE
e2478fde
VZ
300
301HINSTANCE wxhInstance = 0;
302
028e7716 303extern "C" HINSTANCE wxGetInstance()
b568d04f
VZ
304{
305 return wxhInstance;
306}
307
308void wxSetInstance(HINSTANCE hInst)
309{
310 wxhInstance = hInst;
311}
2bda0e17 312
ec67cff1 313#endif // wxUSE_BASE
e2478fde 314