X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/338026503bb5f5826bd9fbea9d2ab51b1ee02beb..b53aea81d2e102224b452ef5bf7aee1132f37c6f:/src/common/init.cpp diff --git a/src/common/init.cpp b/src/common/init.cpp index aaeec98204..d9d3cf0dc7 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: common/init.cpp +// Name: src/common/init.cpp // Purpose: initialisation for the library // Author: Vadim Zeitlin // Modified by: @@ -20,22 +20,21 @@ #include "wx/wxprec.h" #ifdef __BORLANDC__ - #pragma hdrstop + #pragma hdrstop #endif //__BORLANDC__ #ifndef WX_PRECOMP #include "wx/app.h" - #include "wx/debug.h" #include "wx/filefn.h" #include "wx/log.h" - #include "wx/thread.h" #include "wx/intl.h" + #include "wx/module.h" #endif #include "wx/init.h" +#include "wx/thread.h" #include "wx/ptr_scpd.h" -#include "wx/module.h" #include "wx/except.h" #if defined(__WXMSW__) && defined(__WXDEBUG__) @@ -70,8 +69,8 @@ public: // we need a special kind of auto pointer to wxApp which not only deletes the // pointer it holds in its dtor but also resets the global application pointer -wxDECLARE_SCOPED_PTR(wxAppConsole, wxAppPtrBase); -wxDEFINE_SCOPED_PTR(wxAppConsole, wxAppPtrBase); +wxDECLARE_SCOPED_PTR(wxAppConsole, wxAppPtrBase) +wxDEFINE_SCOPED_PTR(wxAppConsole, wxAppPtrBase) class wxAppPtr : public wxAppPtrBase { @@ -177,13 +176,27 @@ static struct InitData static void ConvertArgsToUnicode(int argc, char **argv) { gs_initData.argv = new wchar_t *[argc + 1]; + int wargc = 0; for ( int i = 0; i < argc; i++ ) { - gs_initData.argv[i] = wxStrdup(wxConvLocal.cMB2WX(argv[i])); +#ifdef __DARWIN__ + wxWCharBuffer buf(wxConvFileName->cMB2WX(argv[i])); +#else + wxWCharBuffer buf(wxConvLocal.cMB2WX(argv[i])); +#endif + if ( !buf ) + { + wxLogWarning(_("Command line argument %d couldn't be converted to Unicode and will be ignored."), + i); + } + else // converted ok + { + gs_initData.argv[wargc++] = wxStrdup(buf); + } } - gs_initData.argc = argc; - gs_initData.argv[argc] = NULL; + gs_initData.argc = wargc; + gs_initData.argv[wargc] = NULL; } static void FreeConvertedArgs() @@ -211,12 +224,15 @@ static void FreeConvertedArgs() static bool DoCommonPreInit() { #if wxUSE_LOG + // Reset logging in case we were cleaned up and are being reinitialized. + wxLog::DoCreateOnDemand(); + // install temporary log sink: we can't use wxLogGui before wxApp is // constructed and if we use wxLogStderr, all messages during // initialization simply disappear under Windows // // note that we will delete this log target below - wxLog::SetActiveTarget(new wxLogBuffer); + delete wxLog::SetActiveTarget(new wxLogBuffer); #endif // wxUSE_LOG return true; @@ -233,6 +249,44 @@ static bool DoCommonPostInit() return false; } +#if defined(__WXDEBUG__) + // check if event classes implement Clone() correctly + // NOTE: the check is done against _all_ event classes which are linked to + // the executable currently running, which are not necessarily all + // wxWidgets event classes. + const wxClassInfo *ci = wxClassInfo::GetFirst(); + for (; ci; ci = ci->GetNext()) + { + // is this class derived from wxEvent? + if (!ci->IsKindOf(CLASSINFO(wxEvent)) || wxString(ci->GetClassName()) == "wxEvent") + continue; + + if (!ci->IsDynamic()) + { + wxLogWarning("The event class '%s' should have a DECLARE_DYNAMIC_CLASS macro!", + ci->GetClassName()); + continue; + } + + // yes; test if it implements Clone() correctly + wxEvent* test = wxDynamicCast(ci->CreateObject(),wxEvent); + if (test == NULL) + { + wxLogWarning("The event class '%s' should have a DECLARE_DYNAMIC_CLASS macro!", + ci->GetClassName()); + continue; + } + + wxEvent* cloned = test->Clone(); + if (!cloned || cloned->GetClassInfo() != ci) + wxLogWarning("The event class '%s' does not correctly implement Clone()!", + ci->GetClassName()); + + delete cloned; + delete test; + } +#endif + return true; } @@ -282,6 +336,12 @@ bool wxEntryStart(int& argc, wxChar **argv) return false; } + // remember, possibly modified (e.g. due to removal of toolkit-specific + // parameters), command line arguments in member variables + app->argc = argc; + app->argv = argv; + + wxCallAppCleanup callAppCleanup(app.get()); // for compatibility call the old initialization function too @@ -320,7 +380,7 @@ bool wxEntryStart(int& argc, char **argv) { ConvertArgsToUnicode(argc, argv); - if ( !wxEntryStart(argc, gs_initData.argv) ) + if ( !wxEntryStart(gs_initData.argc, gs_initData.argv) ) { FreeConvertedArgs(); @@ -356,15 +416,16 @@ static void DoCommonPostCleanup() { wxModule::CleanUpModules(); - wxClassInfo::CleanUp(); - // we can't do this in wxApp itself because it doesn't know if argv had // been allocated #if wxUSE_UNICODE FreeConvertedArgs(); #endif // wxUSE_UNICODE - // Note: check for memory leaks is now done via wxDebugContextDumpDelayCounter + // use Set(NULL) and not Get() to avoid creating a message output object on + // demand when we just want to delete it + delete wxMessageOutput::Set(NULL); + #if wxUSE_LOG // and now delete the last logger as well delete wxLog::SetActiveTarget(NULL); @@ -381,8 +442,12 @@ void wxEntryCleanup() { wxTheApp->CleanUp(); - delete wxTheApp; + // reset the global pointer to it to NULL before destroying it as in + // some circumstances this can result in executing the code using + // wxTheApp and using half-destroyed object is no good + wxAppConsole * const app = wxApp::GetInstance(); wxApp::SetInstance(NULL); + delete app; } @@ -448,7 +513,7 @@ int wxEntry(int& argc, char **argv) { ConvertArgsToUnicode(argc, argv); - return wxEntry(argc, gs_initData.argv); + return wxEntry(gs_initData.argc, gs_initData.argv); } #endif // wxUSE_UNICODE @@ -474,9 +539,8 @@ void wxUninitialize() { wxCRIT_SECT_LOCKER(lockInit, gs_initData.csInit); - if ( !--gs_initData.nInitCount ) + if ( --gs_initData.nInitCount == 0 ) { wxEntryCleanup(); } } -