+void wxApp::CleanUp()
+{
+#if wxUSE_LOG
+ // continuing to use user defined log target is unsafe from now on because
+ // some resources may be already unavailable, so replace it by something
+ // more safe
+ wxLog *oldlog = wxLog::SetActiveTarget(new wxLogStderr);
+ if ( oldlog )
+ delete oldlog;
+#endif // wxUSE_LOG
+
+ delete gs_rootWindow;
+
+ wxModule::CleanUpModules();
+
+ if (wxTheColourDatabase)
+ delete wxTheColourDatabase;
+
+ wxTheColourDatabase = (wxColourDatabase*) NULL;
+
+ wxDeleteStockObjects();
+ wxDeleteStockLists();
+
+ delete wxTheApp;
+ wxTheApp = (wxApp*) NULL;
+
+
+ // GL: I'm annoyed ... I don't know where to put this and I don't want to
+ // create a module for that as it's part of the core.
+#if wxUSE_THREADS
+ delete wxPendingEvents;
+ delete wxPendingEventsLocker;
+#endif
+
+ wxClassInfo::CleanUpClasses();
+
+ // Can't do this in wxModule, because fonts are needed by stock lists
+ // (do it after deleting wxTheApp and cleaning modules up, since somebody
+ // may be deleting fonts that lately)
+ delete wxTheFontsManager;
+ wxTheFontsManager = (wxFontsManager*) NULL;
+
+ // 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
+
+#if wxUSE_LOG
+ // do this as the very last thing because everything else can log messages
+ wxLog::DontCreateOnDemand();
+
+ wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL );
+ if (oldLog)
+ delete oldLog;
+#endif // wxUSE_LOG
+
+ wxDestroyMGL_WM();
+ MGL_exit();
+}
+
+
+int wxEntryStart(int argc, char *argv[])
+{
+ return wxApp::Initialize() ? 0 : -1;
+}
+
+
+int wxEntryInitGui()
+{
+ return wxTheApp->OnInitGui() ? 0 : -1;
+}
+
+
+void wxEntryCleanup()
+{
+ wxApp::CleanUp();
+}
+
+
+
+int wxEntry(int argc, char *argv[])
+{
+#ifdef __DJGPP__
+ // VS: disable long filenames under DJGPP as the very first thing,
+ // since SciTech MGL doesn't like them much...
+ wxSetEnv(wxT("LFN"), wxT("N"));
+#endif
+
+#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
+ // This seems to be necessary since there are 'rogue'
+ // objects present at this point (perhaps global objects?)
+ // Setting a checkpoint will ignore them as far as the
+ // memory checking facility is concerned.
+ // Of course you may argue that memory allocated in globals should be
+ // checked, but this is a reasonable compromise.
+ wxDebugContext::SetCheckpoint();
+#endif
+ int err = wxEntryStart(argc, argv);
+ if ( err )
+ return err;
+
+ if ( !wxTheApp )
+ {
+ wxCHECK_MSG( wxApp::GetInitializerFunction(), -1,
+ wxT("wxWindows error: No initializer - use IMPLEMENT_APP macro.\n") );
+
+ wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
+
+ wxObject *test_app = app_ini();
+
+ wxTheApp = (wxApp*) test_app;
+ }
+
+ wxCHECK_MSG( wxTheApp, -1, wxT("wxWindows error: no application object") );
+
+ wxTheApp->argc = argc;
+#if wxUSE_UNICODE
+ wxTheApp->argv = new wxChar*[argc+1];
+ int mb_argc = 0;
+ while (mb_argc < argc)
+ {
+ wxTheApp->argv[mb_argc] = wxStrdup(wxConvLibc.cMB2WX(argv[mb_argc]));
+ mb_argc++;
+ }
+ wxTheApp->argv[mb_argc] = (wxChar *)NULL;
+#else
+ wxTheApp->argv = argv;
+#endif
+
+ wxString name(wxFileNameFromPath(argv[0]));
+ wxStripExtension(name);
+ wxTheApp->SetAppName(name);
+
+ int retValue;
+ retValue = wxEntryInitGui();
+
+ // Here frames insert themselves automatically into wxTopLevelWindows by
+ // getting created in OnInit().
+ if ( retValue == 0 )
+ {
+ if ( !wxTheApp->OnInit() )
+ retValue = -1;
+ }
+
+ if ( retValue == 0 )
+ {
+ /* delete pending toplevel windows (typically a single
+ dialog) so that, if there isn't any left, we don't
+ call OnRun() */
+ wxTheApp->DeletePendingObjects();
+
+ if ( wxTheApp->Initialized() )
+ {
+ wxTheApp->OnRun();
+
+ wxWindow *topWindow = wxTheApp->GetTopWindow();
+ if ( topWindow )
+ {
+ /* Forcibly delete the window. */
+ if (topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
+ topWindow->IsKindOf(CLASSINFO(wxDialog)) )
+ {
+ topWindow->Close(TRUE);
+ wxTheApp->DeletePendingObjects();
+ }
+ else
+ {
+ delete topWindow;
+ wxTheApp->SetTopWindow((wxWindow*) NULL);
+ }
+ }
+
+#if wxUSE_LOG
+ // flush the logged messages if any
+ wxLog *log = wxLog::GetActiveTarget();
+ if (log != NULL && log->HasPendingMessages())
+ log->Flush();
+#endif // wxUSE_LOG
+ retValue = wxTheApp->OnExit();
+ }
+ }
+
+ wxEntryCleanup();
+
+ return retValue;
+}