]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
Corrections to Forty Thieves; wxMemoryDC problem temporarily sorted
[wxWidgets.git] / src / msw / app.cpp
index 6ec239fae493a33a2d17110ea55e67f7462abafa..300ec55493318d9e44e4d752c243aaafb65754e3 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
 #endif
 
 #ifndef WX_PRECOMP
-#include "wx/frame.h"
-#include "wx/app.h"
-#include "wx/utils.h"
-#include "wx/gdicmn.h"
-#include "wx/pen.h"
-#include "wx/brush.h"
-#include "wx/cursor.h"
-#include "wx/icon.h"
-#include "wx/palette.h"
-#include "wx/dc.h"
-#include "wx/dialog.h"
-#include "wx/msgdlg.h"
+  #include "wx/frame.h"
+  #include "wx/app.h"
+  #include "wx/utils.h"
+  #include "wx/gdicmn.h"
+  #include "wx/pen.h"
+  #include "wx/brush.h"
+  #include "wx/cursor.h"
+  #include "wx/icon.h"
+  #include "wx/palette.h"
+  #include "wx/dc.h"
+  #include "wx/dialog.h"
+  #include "wx/msgdlg.h"
 #endif
 
 #include "wx/msw/private.h"
-#include "wx/postscrp.h"
 #include "wx/log.h"
 #include "wx/module.h"
 
-#if USE_WX_RESOURCES
-#include "wx/resource.h"
+#if wxUSE_WX_RESOURCES
+  #include "wx/resource.h"
 #endif
 
-
 #include <string.h>
+#include <ctype.h>
 
 #if defined(__WIN95__) && !defined(__GNUWIN32__)
-#include <commctrl.h>
+  #include <commctrl.h>
+#endif
+
+// use debug CRT functions for memory leak detections in VC++ if we're not
+// using wxWindows own methods
+#if defined(__WXDEBUG__) && defined(_MSC_VER) && !wxUSE_GLOBAL_MEMORY_OPERATORS && !defined(__NO_VC_CRTDBG__)
+    #define wxUSE_VC_CRTDBG
+#else
+    #undef wxUSE_VC_CRTDBG
 #endif
 
-// use debug CRT functions for memory leak detections in VC++
-/* Doesn't work when using the makefiles, for some reason.
-#if defined(__WXDEBUG__) && defined(_MSC_VER)
+#ifdef wxUSE_VC_CRTDBG
+  // VC++ uses this macro as debug/release mode indicator
+  #ifndef _DEBUG
+    #define _DEBUG
+  #endif
+
+  /* Need to undef new if including crtdbg.h */
+  #ifdef new
+  #undef new
+  #endif
+
   #include <crtdbg.h>
+
+  #if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
+  #define new new(__FILE__,__LINE__)
+  #endif
+
 #endif
-*/
 
 extern char *wxBuffer;
 extern char *wxOsVersion;
@@ -69,6 +88,7 @@ HINSTANCE wxhInstance = 0;
 static MSG s_currentMsg;
 wxApp *wxTheApp = NULL;
 
+// @@ why not const? and not static?
 char wxFrameClassName[]         = "wxFrameClass";
 char wxMDIFrameClassName[]      = "wxMDIFrameClass";
 char wxMDIChildFrameClassName[] = "wxMDIChildFrameClass";
@@ -88,131 +108,137 @@ HBRUSH wxDisableButtonBrush = 0;
 LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
 
 #if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
-BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
-    EVT_IDLE(wxApp::OnIdle)
-END_EVENT_TABLE()
+  IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
+
+  BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
+      EVT_IDLE(wxApp::OnIdle)
+      EVT_END_SESSION(wxApp::OnEndSession)
+      EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
+  END_EVENT_TABLE()
 #endif
 
 long wxApp::sm_lastMessageTime = 0;
 
 #ifdef __WIN95__
-static HINSTANCE gs_hRichEdit = NULL;
+  static HINSTANCE gs_hRichEdit = NULL;
 #endif
 
 //// Initialize
 
 bool wxApp::Initialize()
 {
-  wxBuffer = new char[1500];
+    // Some people may wish to use this, but
+    // probably it shouldn't be here by default.
+#ifdef __WXDEBUG__
+//    wxRedirectIOToConsole();
+#endif
+
+    wxBuffer = new char[1500];
 
-/* Doesn't work when using the makefiles, for some reason.
-  #if defined(__WXDEBUG__) && defined(_MSC_VER)
+#ifdef wxUSE_VC_CRTDBG
     // do check for memory leaks on program exit
     // (another useful flag is _CRTDBG_DELAY_FREE_MEM_DF which doesn't free
     //  deallocated memory which may be used to simulate low-memory condition)
     _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
-  #endif // debug build under MS VC++
-*/
+#endif // debug build under MS VC++
 
-#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
+    wxClassInfo::InitializeClasses();
 
-#if !defined(_WINDLL)
-  streambuf* sBuf = new wxDebugStreamBuf;
-#else
-  streambuf* sBuf = NULL;
+#if wxUSE_RESOURCES
+    wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
 #endif
-  ostream* oStr = new ostream(sBuf) ;
-  wxDebugContext::SetStream(oStr, sBuf);
 
-#endif  // USE_MEMORY_TRACING
+    wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
+    wxTheColourDatabase->Initialize();
 
-  wxClassInfo::InitializeClasses();
+    wxInitializeStockLists();
+    wxInitializeStockObjects();
 
-#if USE_RESOURCES
-  wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
+#if wxUSE_WX_RESOURCES
+    wxInitializeResourceSystem();
 #endif
 
-  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
-  wxTheColourDatabase->Initialize();
+    wxBitmap::InitStandardHandlers();
 
-  wxInitializeStockLists();
-  wxInitializeStockObjects();
-
-#if USE_WX_RESOURCES
-  wxInitializeResourceSystem();
-#endif
+#if defined(__WIN95__)
+    InitCommonControls();
+    gs_hRichEdit = LoadLibrary("RICHED32.DLL");
 
-  // For PostScript printing
-#if USE_POSTSCRIPT
-  wxInitializePrintSetupData();
-  wxThePrintPaperDatabase = new wxPrintPaperDatabase;
-  wxThePrintPaperDatabase->CreateDatabase();
+    if (gs_hRichEdit == NULL)
+    {
+      wxMessageBox("Could not initialise Rich Edit DLL");
+    }
 #endif
 
-  wxBitmap::InitStandardHandlers();
-
-#if defined(__WIN95__)
-  InitCommonControls();
-  gs_hRichEdit = LoadLibrary("RICHED32.DLL");
+    int iMsg = 96;
+                       
+   // for OLE, enlarge message queue to be as large as possible
+   while (!SetMessageQueue(iMsg) && (iMsg -= 8));
 
-  if (gs_hRichEdit == NULL)
-  {
-    wxMessageBox("Could not initialise Rich Edit DLL");
-  }
-#endif
+/*
+    DWORD dwOleVer;
+    dwOleVer = CoBuildVersion();
+       
+    // check the OLE library version
+    if (rmm != HIWORD(dwOleVer))
+    {
+        wxMessageBox("Incorrect version of OLE libraries.");
+        return FALSE;
+    }
+*/
 
-#if     defined(WX_DRAG_DROP)
-  // we need to initialize OLE library
-  if ( FAILED(::OleInitialize(NULL)) )
-    wxFatalError(_("Cannot initialize OLE"));
+#ifndef __GNUWIN32__
+    // we need to initialize OLE library
+    if ( FAILED(::OleInitialize(NULL)) )
+      wxFatalError(_("Cannot initialize OLE"));
 #endif
 
 #if CTL3D
-  if (!Ctl3dRegister(wxhInstance))
-    wxFatalError("Cannot register CTL3D");
+    if (!Ctl3dRegister(wxhInstance))
+      wxFatalError("Cannot register CTL3D");
 
-  Ctl3dAutoSubclass(wxhInstance);
+    Ctl3dAutoSubclass(wxhInstance);
 #endif
 
-  g_globalCursor = new wxCursor;
+    g_globalCursor = new wxCursor;
 
-  wxSTD_FRAME_ICON = LoadIcon(wxhInstance, "wxSTD_FRAME");
-  wxSTD_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDIPARENTFRAME");
-  wxSTD_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDICHILDFRAME");
+    wxSTD_FRAME_ICON = LoadIcon(wxhInstance, "wxSTD_FRAME");
+    wxSTD_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDIPARENTFRAME");
+    wxSTD_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDICHILDFRAME");
 
-  wxDEFAULT_FRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_FRAME");
-  wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDIPARENTFRAME");
-  wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDICHILDFRAME");
+    wxDEFAULT_FRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_FRAME");
+    wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDIPARENTFRAME");
+    wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDICHILDFRAME");
 
-  RegisterWindowClasses();
+    RegisterWindowClasses();
 
-  // Create the brush for disabling bitmap buttons
+    // Create the brush for disabling bitmap buttons
 
-  LOGBRUSH lb ;
-  lb.lbStyle = BS_PATTERN;
-  lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ) ;
-  wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ;
-  ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ;
+    LOGBRUSH lb ;
+    lb.lbStyle = BS_PATTERN;
+    lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ) ;
+    wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ;
+    ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ;
 
-#if USE_PENWINDOWS
-  wxRegisterPenWin();
+#if wxUSE_PENWINDOWS
+    wxRegisterPenWin();
 #endif
 
-  wxWinHandleList = new wxList(wxKEY_INTEGER);
+    wxWinHandleList = new wxList(wxKEY_INTEGER);
 
-  // This is to foil optimizations in Visual C++ that
-  // throw out dummy.obj.
+    // This is to foil optimizations in Visual C++ that
+    // throw out dummy.obj.
 #if (_MSC_VER >= 800) && !defined(WXMAKINGDLL)
-  extern char wxDummyChar;
-  if (wxDummyChar) wxDummyChar++;
+    extern char wxDummyChar;
+    if (wxDummyChar) wxDummyChar++;
 #endif
-  wxSetKeyboardHook(TRUE);
 
-  wxModule::RegisterModules();
-  if (!wxModule::InitializeModules())
-    return FALSE;
-  return TRUE;
+    wxSetKeyboardHook(TRUE);
+
+    wxModule::RegisterModules();
+    if (!wxModule::InitializeModules())
+        return FALSE;
+    return TRUE;
 }
 
 //// RegisterWindowClasses
@@ -262,7 +288,7 @@ bool wxApp::RegisterWindowClasses()
   if (!RegisterClass( &wndclass1 ))
   {
 //    wxFatalError("Can't register MDI Frame window class");
-//     return FALSE;
+//  return FALSE;
   }
 
 ///////////////////////////////////////////////////////////////////////
@@ -345,67 +371,74 @@ bool wxApp::RegisterWindowClasses()
 
 void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
 {
-  // Split command line into tokens, as in usual main(argc, argv)
-  char **command = new char*[50];
-
-  int count = 0;
-  char *buf = new char[strlen(lpCmdLine) + 1];
+    wxStringList args;
 
-  // Hangs around until end of app. in case
-  // user carries pointers to the tokens
-
-  /* Model independent strcpy */
-  int i;
-  for (i = 0; (buf[i] = lpCmdLine[i]) != 0; i++)
-  {
-    /* loop */;
-  }
+    wxString cmdLine(lpCmdLine);
+    int count = 0;
 
-  // Get application name
-  char name[200];
-  ::GetModuleFileName(wxhInstance, name, 199);
+    // Get application name
+    char name[260]; // 260 is MAX_PATH value from windef.h
+    ::GetModuleFileName(wxhInstance, name, WXSIZEOF(name));
 
-  // Is it only 16-bit Borland that already copies the program name
-  // to the first argv index?
+    // GNUWIN32 already fills in the first arg with the application name.
 #if !defined(__GNUWIN32__)
-// #if ! (defined(__BORLANDC__) && !defined(__WIN32__))
-  command[count++] = copystring(name);
-// #endif
+    args.Add(name);
+    count ++;
 #endif
 
-  strcpy(name, wxFileNameFromPath(name));
-  wxStripExtension(name);
-  wxTheApp->SetAppName(name);
-
-  /* Break up string */
-  // Treat strings enclosed in double-quotes as single arguments
-    char* str = buf;
-       while (*str)
-       {
-               while (*str && *str <= ' ') str++;      // skip whitespace
-               if (*str == '"')
-               {
-                       str++;
-                       command[count++] = str;
-                       while (*str && *str != '"') str++;
-               }
-               else if (*str)
-               {
-                       command[count++] = str;
-                       while (*str && *str > ' ') str++;
-               }
-               if (*str) *str++ = '\0';
-       }
-
-  wxTheApp->argv = new char*[argc+1];
-  wxTheApp->argv[count] = NULL; /* argv[] is NULL terminated list! */
-  wxTheApp->argc = count;
-
-  for (i = 0; i < count; i++)
-  {
-    wxTheApp->argv[i] = copystring(command[i]);
-  }
-  delete[] buf;
+    strcpy(name, wxFileNameFromPath(name));
+    wxStripExtension(name);
+    wxTheApp->SetAppName(name);
+
+    // Break up string
+    // Treat strings enclosed in double-quotes as single arguments
+    int i = 0;
+    int len = cmdLine.Length();
+    while (i < len)
+    {
+        // Skip whitespace
+        while ((i < len) && isspace(cmdLine.GetChar(i)))
+            i ++;
+
+        if (i < len)
+        {
+            if (cmdLine.GetChar(i) == '"') // We found the start of a string
+            {
+                i ++;
+                int first = i;
+                while ((i < len) && (cmdLine.GetChar(i) != '"'))
+                    i ++;
+
+                wxString arg(cmdLine.Mid(first, (i - first)));
+
+                args.Add(arg);
+                count ++;
+
+                if (i < len)
+                    i ++; // Skip past 2nd quote
+            }
+            else // Unquoted argument
+            {
+                int first = i;
+                while ((i < len) && !isspace(cmdLine.GetChar(i)))
+                    i ++;
+
+                wxString arg(cmdLine.Mid(first, (i - first)));
+
+                args.Add(arg);
+                count ++;
+            }
+        }
+    }
+
+    wxTheApp->argv = new char*[count + 1];
+    for (i = 0; i < count; i++)
+    {
+        wxString arg(args[i]);
+        wxTheApp->argv[i] = copystring((const char*)arg);
+    }
+    wxTheApp->argv[count] = NULL; // argv[] is a NULL-terminated list
+    wxTheApp->argc = count;
 }
 
 //// Cleans up any wxWindows internal structures left lying around
@@ -415,7 +448,7 @@ void wxApp::CleanUp()
   //// COMMON CLEANUP
   wxModule::CleanUpModules();
 
-#if USE_WX_RESOURCES
+#if wxUSE_WX_RESOURCES
   wxCleanUpResourceSystem();
 
 //  wxDefaultResourceTable->ClearTable();
@@ -436,12 +469,6 @@ void wxApp::CleanUp()
   delete wxTheColourDatabase;
   wxTheColourDatabase = NULL;
 
-#if USE_POSTSCRIPT
-  wxInitializePrintSetupData(FALSE);
-  delete wxThePrintPaperDatabase;
-  wxThePrintPaperDatabase = NULL;
-#endif
-
   wxBitmap::CleanUpHandlers();
 
   delete[] wxBuffer;
@@ -456,7 +483,7 @@ void wxApp::CleanUp()
     FreeLibrary(gs_hRichEdit);
 #endif
 
-#if USE_PENWINDOWS
+#if wxUSE_PENWINDOWS
   wxCleanUpPenWin();
 #endif
 
@@ -477,7 +504,7 @@ void wxApp::CleanUp()
   if ( wxDisableButtonBrush )
     ::DeleteObject( wxDisableButtonBrush ) ;
 
-#if     defined(WX_DRAG_DROP)
+#ifndef __GNUWIN32__
   ::OleUninitialize();
 #endif
 
@@ -490,6 +517,23 @@ void wxApp::CleanUp()
 
   wxClassInfo::CleanUpClasses();
 
+  delete wxTheApp;
+  wxTheApp = NULL;
+
+#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
+  // At this point we want to check if there are any memory
+  // blocks that aren't part of the wxDebugContext itself,
+  // as a special case. Then when dumping we need to ignore
+  // wxDebugContext, too.
+  if (wxDebugContext::CountObjectsLeft() > 0)
+  {
+      wxLogDebug("There were memory leaks.");
+      wxDebugContext::Dump();
+      wxDebugContext::PrintStatistics();
+  }
+//  wxDebugContext::SetStream(NULL, NULL);
+#endif
+
   // do it as the very last thing because everything else can log messages
   wxLog::DontCreateOnDemand();
   delete wxLog::SetActiveTarget(NULL);
@@ -498,34 +542,36 @@ void wxApp::CleanUp()
 #if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
 
 //// Main wxWindows entry point
-
-int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *lpCmdLine,
-                    int nCmdShow, bool enterLoop)
+int wxEntry(WXHINSTANCE hInstance,
+            WXHINSTANCE WXUNUSED(hPrevInstance),
+            char *lpCmdLine,
+            int nCmdShow,
+            bool enterLoop)
 {
+#ifndef __WXDEBUG__ // take everything into a try-except block in release build
+  try {
+#endif
+
   wxhInstance = (HINSTANCE) hInstance;
 
   if (!wxApp::Initialize())
     return 0;
 
-  // The app may have declared a global application object, but we recommend
-  // the IMPLEMENT_APP macro is used instead, which sets an initializer function
-  // for delayed, dynamic app object construction.
+  // create the application object or ensure that one already exists
   if (!wxTheApp)
   {
-       if (!wxApp::GetInitializerFunction())
-       {
-       MessageBox(NULL, "No initializer - use IMPLEMENT_APP macro.", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
-               return 0;
-       }
+    // The app may have declared a global application object, but we recommend
+    // the IMPLEMENT_APP macro is used instead, which sets an initializer
+    // function for delayed, dynamic app object construction.
+    wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
+                 "No initializer - use IMPLEMENT_APP macro." );
 
-       wxTheApp = (* wxApp::GetInitializerFunction()) ();
+    wxTheApp = (*wxApp::GetInitializerFunction()) ();
   }
 
-  if (!wxTheApp) {
-    MessageBox(NULL, "You have to define an instance of wxApp!", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
-    return 0;
-  }
+  wxCHECK_MSG( wxTheApp, 0, "You have to define an instance of wxApp!" );
 
+  // save the WinMain() parameters
   wxTheApp->ConvertToStandardCommandArgs(lpCmdLine);
   wxTheApp->m_nCmdShow = nCmdShow;
 
@@ -533,69 +579,56 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *lp
   // but this call is provided for compatibility across platforms.
   wxTheApp->OnInitGui() ;
 
-  if (!wxTheApp->OnInit())
-  {
-       wxTheApp->DeletePendingObjects();
-        wxTheApp->OnExit();
-        wxApp::CleanUp();
-
-        delete wxTheApp;
-        wxTheApp = NULL;
-
-           return 0;
-  }
-
-  if (!enterLoop)
-       return 0;
-
-  int retValue = 1;
+  int retValue = 0;
 
-/* New behaviour - leave it to the app to show the top window
-  if (wxTheApp->GetTopWindow()) {
-    // show the toplevel frame, only if we are not iconized (from MS-Windows)
-    if(wxTheApp->GetShowFrameOnInit() && (nCmdShow!=SW_HIDE)) wxTheApp->GetTopWindow()->Show(TRUE);
+  if ( wxTheApp->OnInit() )
+  {
+      if ( enterLoop )
+      {
+          retValue = wxTheApp->OnRun();
+      }
   }
-*/
+  //else: app initialization failed, so we skipped OnRun()
 
-  retValue = wxTheApp->OnRun();
-
-  if (wxTheApp->GetTopWindow())
+  wxWindow *topWindow = wxTheApp->GetTopWindow();
+  if ( topWindow )
   {
-    // Forcibly delete the window.
-       if (wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)) ||
-           wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog)))
-       {
-       wxTheApp->GetTopWindow()->Close(TRUE);
-       wxTheApp->DeletePendingObjects();
-       }
-       else
-       {
-               delete wxTheApp->GetTopWindow();
-               wxTheApp->SetTopWindow(NULL);
-       }
+      // Forcibly delete the window.
+      if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
+           topWindow->IsKindOf(CLASSINFO(wxDialog)) )
+      {
+          topWindow->Close(TRUE);
+          wxTheApp->DeletePendingObjects();
+      }
+      else
+      {
+          delete topWindow;
+          wxTheApp->SetTopWindow(NULL);
+      }
   }
 
   wxTheApp->OnExit();
-  wxApp::CleanUp();
 
-  delete wxTheApp;
-  wxTheApp = NULL;
+  // flush the logged messages if any
+  wxLog *pLog = wxLog::GetActiveTarget();
+  if ( pLog != NULL && pLog->HasPendingMessages() )
+    pLog->Flush();
 
-#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
-  // At this point we want to check if there are any memory
-  // blocks that aren't part of the wxDebugContext itself,
-  // as a special case. Then when dumping we need to ignore
-  // wxDebugContext, too.
-  if (wxDebugContext::CountObjectsLeft() > 0)
-  {
-    wxTrace("There were memory leaks.\n");
-    wxDebugContext::Dump();
-    wxDebugContext::PrintStatistics();
-  }
-  wxDebugContext::SetStream(NULL, NULL);
-#endif
+
+  wxApp::CleanUp();
 
   return retValue;
+#ifndef __WXDEBUG__ // catch exceptions only in release build
+  }
+  except ( EXCEPTION_EXECUTE_HANDLER ) {
+    /*
+    if ( wxTheApp )
+      wxTheApp->OnFatalException();
+    */
+
+    ::ExitProcess(3); // the same exit code as abort()
+  }
+#endif //debug
 }
 
 #else /*  _WINDLL  */
@@ -613,13 +646,13 @@ int wxEntry(WXHINSTANCE hInstance)
 
   if (!wxTheApp)
   {
-       if (!wxApp::GetInitializerFunction())
-       {
-       MessageBox(NULL, "No initializer - use IMPLEMENT_APP macro.", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
-               return 0;
-       }
+    if (!wxApp::GetInitializerFunction())
+    {
+      MessageBox(NULL, "No initializer - use IMPLEMENT_APP macro.", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
+    return 0;
+    }
 
-       wxTheApp = (* wxApp::GetInitializerFunction()) ();
+    wxTheApp = (* wxApp::GetInitializerFunction()) ();
   }
 
   if (!wxTheApp) {
@@ -672,7 +705,7 @@ wxApp::~wxApp()
   {
     delete[] argv[i];
   }
-  delete argv;
+  delete[] argv;
 }
 
 bool wxApp::Initialized()
@@ -832,40 +865,40 @@ void wxApp::OnIdle(wxIdleEvent& event)
 bool wxApp::SendIdleEvents()
 {
     bool needMore = FALSE;
-       wxNode* node = wxTopLevelWindows.First();
-       while (node)
-       {
-               wxWindow* win = (wxWindow*) node->Data();
-               if (SendIdleEvents(win))
+  wxNode* node = wxTopLevelWindows.First();
+  while (node)
+  {
+    wxWindow* win = (wxWindow*) node->Data();
+    if (SendIdleEvents(win))
             needMore = TRUE;
 
-               node = node->Next();
-       }
+    node = node->Next();
+  }
     return needMore;
 }
 
 // Send idle event to window and all subwindows
 bool wxApp::SendIdleEvents(wxWindow* win)
 {
-    bool needMore = FALSE;
+  bool needMore = FALSE;
 
-       wxIdleEvent event;
-       event.SetEventObject(win);
-       win->ProcessEvent(event);
+  wxIdleEvent event;
+  event.SetEventObject(win);
+  win->GetEventHandler()->ProcessEvent(event);
 
-    if (event.MoreRequested())
-        needMore = TRUE;
+  if (event.MoreRequested())
+    needMore = TRUE;
 
-       wxNode* node = win->GetChildren()->First();
-       while (node)
-       {
-               wxWindow* win = (wxWindow*) node->Data();
-               if (SendIdleEvents(win))
-            needMore = TRUE;
+  wxNode* node = win->GetChildren().First();
+  while (node)
+  {
+    wxWindow* win = (wxWindow*) node->Data();
+    if (SendIdleEvents(win))
+      needMore = TRUE;
 
-               node = node->Next();
-       }
-    return needMore ;
+    node = node->Next();
+  }
+  return needMore ;
 }
 
 void wxApp::DeletePendingObjects()
@@ -886,6 +919,23 @@ void wxApp::DeletePendingObjects()
   }
 }
 
+void wxApp::OnEndSession(wxCloseEvent& event)
+{
+    if (GetTopWindow())
+        GetTopWindow()->Close(TRUE);
+}
+
+// Default behaviour: close the application with prompts. The
+// user can veto the close, and therefore the end session.
+void wxApp::OnQueryEndSession(wxCloseEvent& event)
+{
+    if (GetTopWindow())
+    {
+        if (!GetTopWindow()->Close(!event.CanVeto()))
+            event.Veto(TRUE);
+    }
+}
+
 wxLog* wxApp::CreateLogTarget()
 {
     return new wxLogGui;
@@ -915,30 +965,30 @@ int wxApp::GetComCtl32Version() const
 
         if (! theProc)
         {                    // not found, must be 4.00
-                       version = 400;
+      version = 400;
         }
         else
         {
-                       // The following symbol are unique to 4.71
-                       //   DllInstall
-                       //   FlatSB_EnableScrollBar FlatSB_GetScrollInfo FlatSB_GetScrollPos
-                       //   FlatSB_GetScrollProp FlatSB_GetScrollRange FlatSB_SetScrollInfo
-                       //   FlatSB_SetScrollPos FlatSB_SetScrollProp FlatSB_SetScrollRange
-                       //   FlatSB_ShowScrollBar
-                       //   _DrawIndirectImageList _DuplicateImageList
-                       //   InitializeFlatSB
-                       //   UninitializeFlatSB
-                       // we could check for any of these - I chose DllInstall
-                       FARPROC theProc = ::GetProcAddress(theModule, "DllInstall");
-                       if (! theProc)
-                       {
-                               // not found, must be 4.70
-                               version = 470;
-                       }
-                       else
-                       {                         // found, must be 4.71
-                               version = 471;
-                       }
+      // The following symbol are unique to 4.71
+      //   DllInstall
+      //   FlatSB_EnableScrollBar FlatSB_GetScrollInfo FlatSB_GetScrollPos
+      //   FlatSB_GetScrollProp FlatSB_GetScrollRange FlatSB_SetScrollInfo
+      //   FlatSB_SetScrollPos FlatSB_SetScrollProp FlatSB_SetScrollRange
+      //   FlatSB_ShowScrollBar
+      //   _DrawIndirectImageList _DuplicateImageList
+      //   InitializeFlatSB
+      //   UninitializeFlatSB
+      // we could check for any of these - I chose DllInstall
+      FARPROC theProc = ::GetProcAddress(theModule, "DllInstall");
+      if (! theProc)
+      {
+        // not found, must be 4.70
+        version = 470;
+      }
+      else
+      {                         // found, must be 4.71
+        version = 471;
+      }
         }
     }
     return version;
@@ -967,12 +1017,11 @@ bool wxYield()
 
 HINSTANCE wxGetInstance()
 {
-       return wxhInstance;
+  return wxhInstance;
 }
 
 // For some reason, with MSVC++ 1.5, WinMain isn't linked in properly
 // if in a separate file. So include it here to ensure it's linked.
 #if (defined(_MSC_VER) && !defined(__WIN32__)) || defined(__GNUWIN32__)
-#include "main.cpp"
+  #include "main.cpp"
 #endif
-