X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/005b5298e40a7665a07067ab2a56ae8be4102dfb..2b9a7d4cc2f5f55df3d83f7cf2160cf9a509a4f2:/src/common/init.cpp diff --git a/src/common/init.cpp b/src/common/init.cpp index 58e2b591a2..a225bf6833 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -35,6 +35,7 @@ #include "wx/ptr_scpd.h" #include "wx/module.h" +#include "wx/except.h" #if defined(__WXMSW__) && defined(__WXDEBUG__) #include "wx/msw/msvcrt.h" @@ -59,34 +60,40 @@ class wxDummyConsoleApp : public wxAppConsole { public: + wxDummyConsoleApp() { } + virtual int OnRun() { wxFAIL_MSG( _T("unreachable code") ); return 0; } + + DECLARE_NO_COPY_CLASS(wxDummyConsoleApp) }; // we need a special kind of auto pointer to wxApp which not only deletes the -// pointer it holds in its dtor but also resets wxTheApp -wxDECLARE_SCOPED_PTR(wxApp, wxAppPtrBase); -wxDEFINE_SCOPED_PTR(wxApp, wxAppPtrBase); +// pointer it holds in its dtor but also resets the global application pointer +wxDECLARE_SCOPED_PTR(wxAppConsole, wxAppPtrBase); +wxDEFINE_SCOPED_PTR(wxAppConsole, wxAppPtrBase); class wxAppPtr : public wxAppPtrBase { public: - wxEXPLICIT wxAppPtr(wxApp *ptr = NULL) : wxAppPtrBase(ptr) { } + wxEXPLICIT wxAppPtr(wxAppConsole *ptr = NULL) : wxAppPtrBase(ptr) { } ~wxAppPtr() { if ( get() ) { // the pointer is going to be deleted in the base class dtor, don't // leave the dangling pointer! - wxTheApp = NULL; + wxApp::SetInstance(NULL); } } - void Set(wxApp *ptr) + void Set(wxAppConsole *ptr) { reset(ptr); - wxTheApp = ptr; + wxApp::SetInstance(ptr); } + + DECLARE_NO_COPY_CLASS(wxAppPtr) }; // class to ensure that wxAppBase::CleanUp() is called if our Initialize() @@ -94,13 +101,13 @@ public: class wxCallAppCleanup { public: - wxCallAppCleanup(wxApp *app) : m_app(app) { } + wxCallAppCleanup(wxAppConsole *app) : m_app(app) { } ~wxCallAppCleanup() { if ( m_app ) m_app->CleanUp(); } void Dismiss() { m_app = NULL; } private: - wxApp *m_app; + wxAppConsole *m_app; }; // another tiny class which simply exists to ensure that wxEntryCleanup is @@ -152,6 +159,8 @@ static struct InitData // free it when doing cleanup to avoid memory leaks wchar_t **argv; #endif // wxUSE_UNICODE + + DECLARE_NO_COPY_CLASS(InitData) } gs_initData; // ============================================================================ @@ -172,6 +181,7 @@ static void ConvertArgsToUnicode(int argc, char **argv) gs_initData.argv[i] = wxStrdup(wxConvLocal.cMB2WX(argv[i])); } + gs_initData.argc = argc; gs_initData.argv[argc] = NULL; } @@ -186,6 +196,7 @@ static void FreeConvertedArgs() delete [] gs_initData.argv; gs_initData.argv = NULL; + gs_initData.argc = 0; } } @@ -198,8 +209,6 @@ static void FreeConvertedArgs() // initialization which is always done (not customizable) before wxApp creation static bool DoCommonPreInit() { - wxClassInfo::InitializeClasses(); - return true; } @@ -245,25 +254,22 @@ bool wxEntryStart(int& argc, wxChar **argv) { // either IMPLEMENT_APP() was not used at all or it failed -- in any // case we still need something - // - // NB: cast is needed because for the backwards-compatibility reasons - // wxTheApp is really a wxApp and not just wxAppConsole... - app.Set((wxApp *)new wxDummyConsoleApp); + app.Set(new wxDummyConsoleApp); } // wxApp initialization: this can be customized // -------------------------------------------- - if ( !wxTheApp->Initialize(argc, argv) ) + if ( !app->Initialize(argc, argv) ) { return false; } - wxCallAppCleanup callAppCleanup(wxTheApp); + wxCallAppCleanup callAppCleanup(app.get()); // for compatibility call the old initialization function too - if ( !wxTheApp->OnInitGui() ) + if ( !app->OnInitGui() ) return false; @@ -306,27 +312,27 @@ bool wxEntryStart(int& argc, char **argv) // clean up // ---------------------------------------------------------------------------- -// cleanup done before destroying wxTheApp +// cleanup done before destroying wxTheApp static void DoCommonPreCleanup() { #if wxUSE_LOG // flush the logged messages if any and install a 'safer' log target: the // default one (wxLogGui) can't be used after the resources are freed just // below and the user supplied one might be even more unsafe (using any - // wxWindows GUI function is unsafe starting from now) + // wxWidgets GUI function is unsafe starting from now) wxLog::DontCreateOnDemand(); // this will flush the old messages if any delete wxLog::SetActiveTarget(new wxLogStderr); #endif // wxUSE_LOG - - wxModule::CleanUpModules(); } // cleanup done after destroying wxTheApp static void DoCommonPostCleanup() { - wxClassInfo::CleanUpClasses(); + wxModule::CleanUpModules(); + + wxClassInfo::CleanUp(); // we can't do this in wxApp itself because it doesn't know if argv had // been allocated @@ -334,6 +340,7 @@ static void DoCommonPostCleanup() FreeConvertedArgs(); #endif // wxUSE_UNICODE + // Note: check for memory leaks is now done via wxDebugContextDumpDelayCounter #if wxUSE_LOG // and now delete the last logger as well delete wxLog::SetActiveTarget(NULL); @@ -351,34 +358,30 @@ void wxEntryCleanup() wxTheApp->CleanUp(); delete wxTheApp; - wxTheApp = NULL; + wxApp::SetInstance(NULL); } DoCommonPostCleanup(); - - // check for memory leaks -#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - if (wxDebugContext::CountObjectsLeft(TRUE) > 0) - { - wxLogDebug(wxT("There were memory leaks.\n")); - wxDebugContext::Dump(); - wxDebugContext::PrintStatistics(); - } -#endif // Debug - } // ---------------------------------------------------------------------------- // wxEntry // ---------------------------------------------------------------------------- -#if !defined(__WXMSW__) || !wxUSE_ON_FATAL_EXCEPTION +// for MSW the real wxEntry is defined in msw/main.cpp +#ifndef __WXMSW__ #define wxEntryReal wxEntry -#endif // !(__WXMSW__ && wxUSE_ON_FATAL_EXCEPTION) +#endif // !__WXMSW__ int wxEntryReal(int& argc, wxChar **argv) { +#if wxUSE_LOG + // Create a non-GUI log target, to be used until GUI (if any) is ready. + // Target will be reset by wxAppConsole::Initialize, when GUI logging will work. + wxLog::GetActiveTarget(); +#endif + // library initialization if ( !wxEntryStart(argc, argv) ) { @@ -391,60 +394,31 @@ int wxEntryReal(int& argc, wxChar **argv) WX_SUPPRESS_UNUSED_WARN(cleanupOnExit); - // app initialization - if ( !wxTheApp->OnInit() ) + wxTRY { - // don't call OnExit() if OnInit() failed - return -1; - } - // app execution - int retValue = wxTheApp->OnRun(); - - // why should we do this? it doesn't close all window, just one of them and - // this shouldn't be necessary anyhow... -#if 0 - // close any remaining windows - wxWindow *topWindow = wxTheApp->GetTopWindow(); - if ( topWindow ) - { - // forcibly delete the window. - topWindow->Destroy(); - - // collect the dead objects - wxTheApp->DeletePendingObjects(); - } -#endif // 0 - - // app clean up - wxTheApp->OnExit(); - - return retValue; -} - -// wrap real wxEntry in a try-except block to be able to call -// OnFatalException() if necessary -#if defined(__WXMSW__) && wxUSE_ON_FATAL_EXCEPTION + // app initialization + if ( !wxTheApp->CallOnInit() ) + { + // don't call OnExit() if OnInit() failed + return -1; + } -extern unsigned long wxGlobalSEHandler(); + // ensure that OnExit() is called if OnInit() had succeeded + class CallOnExit + { + public: + ~CallOnExit() { wxTheApp->OnExit(); } + } callOnExit; -int wxEntry(int& argc, wxChar **argv) -{ - __try - { - return wxEntryReal(argc, argv); - } - __except ( wxGlobalSEHandler() ) - { - ::ExitProcess(3); // the same exit code as abort() + WX_SUPPRESS_UNUSED_WARN(callOnExit); - // this code is unreachable but put it here to suppress warnings - return -1; + // app execution + return wxTheApp->OnRun(); } + wxCATCH_ALL( wxTheApp->OnUnhandledException(); return -1; ) } -#endif // __WXMSW__ && wxUSE_ON_FATAL_EXCEPTION - #if wxUSE_UNICODE // as with wxEntryStart, we provide an ANSI wrapper