]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
no message
[wxWidgets.git] / src / msw / app.cpp
index 2380393bfd4e94dff12297a1cd35f3f4a4bfdf5f..7d5b43fe2c32d8047020120278d35d753c8492f5 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__
@@ -14,7 +14,6 @@
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
-#define IN_WX_MAIN_CPP
 #include "wx/wxprec.h"
 
 #if defined(__BORLANDC__)
 #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++
-/* Doesn't work when using the makefiles, for some reason.
+/* Here we go again commenting it out. PLEASE don't
+ * uncomment this again.
 #if defined(__WXDEBUG__) && defined(_MSC_VER)
+  // VC++ uses this macro as debug/release mode indicator
+  #ifndef _DEBUG
+    #define _DEBUG
+  #endif
+
   #include <crtdbg.h>
 #endif
 */
@@ -70,6 +74,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";
@@ -89,54 +94,98 @@ 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
 
-bool wxApp::Initialize(WXHINSTANCE instance)
+//// Initialize
+
+bool wxApp::Initialize()
 {
-  HINSTANCE hInstance = (HINSTANCE) instance;
+  wxBuffer = new char[1500];
 
-  CommonInit();
+/* PLEASE don't uncomment this again. IT DOESN'T WORK when building
+ * using the makefile.
+  #if defined(__WXDEBUG__) && defined(_MSC_VER)
+    // 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++
+*/
 
-#if defined(__WIN95__)
-  InitCommonControls();
-  gs_hRichEdit = LoadLibrary("RICHED32.DLL");
+  #if (WXDEBUG && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
+    #if defined(_WINDLL)
+      streambuf* sBuf = NULL;
+    #else  // EXE
+      streambuf* sBuf = new wxDebugStreamBuf;
+    #endif // DLL
 
-  if (gs_hRichEdit == NULL)
-  {
-    wxMessageBox("Could not initialise Rich Edit DLL");
-  }
-#endif
+    ostream* oStr = new ostream(sBuf) ;
+    wxDebugContext::SetStream(oStr, sBuf);
+  #endif  // wxUSE_MEMORY_TRACING
 
-#if     defined(WX_DRAG_DROP)
-  // we need to initialize OLE library
-  if ( FAILED(::OleInitialize(NULL)) )
-    wxFatalError(_("Cannot initialize OLE"));
-#endif
+  wxClassInfo::InitializeClasses();
 
-#if CTL3D
-  if (!Ctl3dRegister(hInstance))
-    wxFatalError("Cannot register CTL3D");
+  #if wxUSE_RESOURCES
+    wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
+  #endif
 
-  Ctl3dAutoSubclass(hInstance);
-#endif
+  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
+  wxTheColourDatabase->Initialize();
+
+  wxInitializeStockLists();
+  wxInitializeStockObjects();
+
+  #if wxUSE_WX_RESOURCES
+    wxInitializeResourceSystem();
+  #endif
+
+  wxBitmap::InitStandardHandlers();
+
+  #if defined(__WIN95__)
+    InitCommonControls();
+    gs_hRichEdit = LoadLibrary("RICHED32.DLL");
+
+    if (gs_hRichEdit == NULL)
+    {
+      wxMessageBox("Could not initialise Rich Edit DLL");
+    }
+  #endif
+
+  #if  defined(WX_DRAG_DROP)
+    // we need to initialize OLE library
+    if ( FAILED(::OleInitialize(NULL)) )
+      wxFatalError(_("Cannot initialize OLE"));
+  #endif
+
+  #if CTL3D
+    if (!Ctl3dRegister(wxhInstance))
+      wxFatalError("Cannot register CTL3D");
 
-  wxSTD_FRAME_ICON = LoadIcon(hInstance, "wxSTD_FRAME");
-  wxSTD_MDIPARENTFRAME_ICON = LoadIcon(hInstance, "wxSTD_MDIPARENTFRAME");
-  wxSTD_MDICHILDFRAME_ICON = LoadIcon(hInstance, "wxSTD_MDICHILDFRAME");
+    Ctl3dAutoSubclass(wxhInstance);
+  #endif
 
-  wxDEFAULT_FRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_FRAME");
-  wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_MDIPARENTFRAME");
-  wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_MDICHILDFRAME");
+  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");
+
+  wxDEFAULT_FRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_FRAME");
+  wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDIPARENTFRAME");
+  wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDICHILDFRAME");
 
   RegisterWindowClasses();
 
@@ -144,22 +193,23 @@ bool wxApp::Initialize(WXHINSTANCE instance)
 
   LOGBRUSH lb ;
   lb.lbStyle = BS_PATTERN;
-  lb.lbHatch = (int)LoadBitmap( hInstance, "wxDISABLE_BUTTON_BITMAP" ) ;
+  lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ) ;
   wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ;
   ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ;
 
-#if USE_PENWINDOWS
-  wxRegisterPenWin();
-#endif
+  #if wxUSE_PENWINDOWS
+    wxRegisterPenWin();
+  #endif
 
   wxWinHandleList = new wxList(wxKEY_INTEGER);
 
   // 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++;
-#endif
+  #if (_MSC_VER >= 800) && !defined(WXMAKINGDLL)
+    extern char wxDummyChar;
+    if (wxDummyChar) wxDummyChar++;
+  #endif
+
   wxSetKeyboardHook(TRUE);
 
   wxModule::RegisterModules();
@@ -168,6 +218,8 @@ bool wxApp::Initialize(WXHINSTANCE instance)
   return TRUE;
 }
 
+//// RegisterWindowClasses
+
 bool wxApp::RegisterWindowClasses()
 {
 ///////////////////////////////////////////////////////////////////////
@@ -185,7 +237,7 @@ bool wxApp::RegisterWindowClasses()
 //  wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
   wndclass.lpszMenuName  = NULL;
 #ifdef _MULTIPLE_INSTANCES
-  sprintf( wxFrameClassName,"wxFrameClass%d", hInstance );
+  sprintf( wxFrameClassName,"wxFrameClass%d", wxhInstance );
 #endif
   wndclass.lpszClassName = wxFrameClassName;
 
@@ -213,7 +265,7 @@ bool wxApp::RegisterWindowClasses()
   if (!RegisterClass( &wndclass1 ))
   {
 //    wxFatalError("Can't register MDI Frame window class");
-//     return FALSE;
+//  return FALSE;
   }
 
 ///////////////////////////////////////////////////////////////////////
@@ -292,12 +344,114 @@ bool wxApp::RegisterWindowClasses()
   return TRUE;
 }
 
-// Cleans up any wxWindows internal structures left lying around
+//// Convert Windows to argc, argv style
+
+void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
+{
+    wxStringList args;
+
+    wxString cmdLine(lpCmdLine);
+    int count = 0;
+
+    // Get application name
+    char name[260]; // 260 is MAX_PATH value from windef.h
+    ::GetModuleFileName(wxhInstance, name, WXSIZEOF(name));
+
+    // GNUWIN32 already fills in the first arg with the application name.
+#if !defined(__GNUWIN32__)
+    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
+    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
+
 void wxApp::CleanUp()
 {
+  //// COMMON CLEANUP
   wxModule::CleanUpModules();
 
-  CommonCleanUp();
+#if wxUSE_WX_RESOURCES
+  wxCleanUpResourceSystem();
+
+//  wxDefaultResourceTable->ClearTable();
+#endif
+
+  // Indicate that the cursor can be freed,
+  // so that cursor won't be deleted by deleting
+  // the bitmap list before g_globalCursor goes out
+  // of scope (double deletion of the cursor).
+  wxSetCursor(wxNullCursor);
+  delete g_globalCursor;
+
+  wxDeleteStockObjects() ;
+
+  // Destroy all GDI lists, etc.
+  wxDeleteStockLists();
+
+  delete wxTheColourDatabase;
+  wxTheColourDatabase = NULL;
+
+  wxBitmap::CleanUpHandlers();
+
+  delete[] wxBuffer;
+  wxBuffer = NULL;
+
+  //// WINDOWS-SPECIFIC CLEANUP
 
   wxSetKeyboardHook(FALSE);
 
@@ -306,7 +460,7 @@ void wxApp::CleanUp()
     FreeLibrary(gs_hRichEdit);
 #endif
 
-#if USE_PENWINDOWS
+#if wxUSE_PENWINDOWS
   wxCleanUpPenWin();
 #endif
 
@@ -338,240 +492,79 @@ void wxApp::CleanUp()
   if (wxWinHandleList)
     delete wxWinHandleList ;
 
+  wxClassInfo::CleanUpClasses();
+
   // do it as the very last thing because everything else can log messages
   wxLog::DontCreateOnDemand();
   delete wxLog::SetActiveTarget(NULL);
 }
 
-void wxApp::CommonInit()
-{
-#ifdef __WXMSW__
-  wxBuffer = new char[1500];
-#else
-  wxBuffer = new char[BUFSIZ + 512];
-#endif
-
-  wxClassInfo::InitializeClasses();
-
-#if USE_RESOURCES
-  wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
-#endif
-
-  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
-  wxTheColourDatabase->Initialize();
-
-  wxInitializeStockLists();
-  wxInitializeStockObjects();
-
-#if USE_WX_RESOURCES
-  wxInitializeResourceSystem();
-#endif
-
-  // For PostScript printing
-#if USE_POSTSCRIPT
-  wxInitializePrintSetupData();
-  wxThePrintPaperDatabase = new wxPrintPaperDatabase;
-  wxThePrintPaperDatabase->CreateDatabase();
-#endif
-
-  wxBitmap::InitStandardHandlers();
-
-  g_globalCursor = new wxCursor;
-}
-
-void wxApp::CommonCleanUp()
-{
-#if USE_WX_RESOURCES
-  wxCleanUpResourceSystem();
-
-//  wxDefaultResourceTable->ClearTable();
-#endif
-
-  // Indicate that the cursor can be freed,
-  // so that cursor won't be deleted by deleting
-  // the bitmap list before g_globalCursor goes out
-  // of scope (double deletion of the cursor).
-  wxSetCursor(wxNullCursor);
-  delete g_globalCursor;
-
-  wxDeleteStockObjects() ;
-
-  // Destroy all GDI lists, etc.
-  wxDeleteStockLists();
-
-  delete wxTheColourDatabase;
-  wxTheColourDatabase = NULL;
-
-#if USE_POSTSCRIPT
-  wxInitializePrintSetupData(FALSE);
-  delete wxThePrintPaperDatabase;
-  wxThePrintPaperDatabase = NULL;
-#endif
-
-  wxBitmap::CleanUpHandlers();
-
-  delete[] wxBuffer;
-  wxBuffer = NULL;
-}
-
 #if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
 
-// Main wxWindows entry point
-
-int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_lpCmdLine,
-                    int nCmdShow, bool enterLoop)
+//// Main wxWindows entry point
+int wxEntry(WXHINSTANCE hInstance,
+            WXHINSTANCE WXUNUSED(hPrevInstance),
+            char *lpCmdLine,
+            int nCmdShow,
+            bool enterLoop)
 {
-  wxhInstance = (HINSTANCE) hInstance;
-
-/* Doesn't work when using the makefiles, for some reason.
-  #if defined(__WXDEBUG__) && defined(_MSC_VER)
-    // 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++
-*/
-
-#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
-
-#if !defined(_WINDLL)
-  streambuf* sBuf = new wxDebugStreamBuf;
-#else
-  streambuf* sBuf = NULL;
+#ifndef __WXDEBUG__ // take everything into a try-except block in release build
+  try {
 #endif
-  ostream* oStr = new ostream(sBuf) ;
-  wxDebugContext::SetStream(oStr, sBuf);
 
-#endif  // USE_MEMORY_TRACING
+  wxhInstance = (HINSTANCE) hInstance;
 
-  if (!wxApp::Initialize((WXHINSTANCE) wxhInstance))
+  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;
-       }
-
-       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;
-  }
+    // 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." );
 
-  // Split command line into tokens, as in usual main(argc, argv)
-  char **command = new char*[50];
-
-  int count = 0;
-  char *buf = new char[strlen(m_lpCmdLine) + 1];
-
-  // Hangs around until end of app. in case
-  // user carries pointers to the tokens
-
-  /* Model independent strcpy */
-  int i;
-  for (i = 0; (buf[i] = m_lpCmdLine[i]) != 0; i++)
-  {
-    /* loop */;
+    wxTheApp = (*wxApp::GetInitializerFunction()) ();
   }
 
-  // Get application name
-  char name[200];
-  ::GetModuleFileName(wxhInstance, name, 199);
-
-  // Is it only 16-bit Borland that already copies the program name
-  // to the first argv index?
-#if !defined(__GNUWIN32__)
-// #if ! (defined(__BORLANDC__) && !defined(__WIN32__))
-  command[count++] = copystring(name);
-// #endif
-#endif
+  wxCHECK_MSG( wxTheApp, 0, "You have to define an instance of wxApp!" );
 
-  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';
-       }
-  command[count] = NULL; /* argv[] is NULL terminated list! */
-
-  wxTheApp->argc = count;
-  wxTheApp->argv = command;
+  // save the WinMain() parameters
+  wxTheApp->ConvertToStandardCommandArgs(lpCmdLine);
   wxTheApp->m_nCmdShow = nCmdShow;
 
   // GUI-specific initialisation. In fact on Windows we don't have any,
   // but this call is provided for compatibility across platforms.
   wxTheApp->OnInitGui() ;
 
-  if (!wxTheApp->OnInit())
-  {
-       wxTheApp->DeletePendingObjects();
-        wxTheApp->OnExit();
-        wxApp::CleanUp();
-
-        delete wxTheApp;
-        wxTheApp = NULL;
-
-        delete [] buf ;
-
-        // TODO: This should really be cleaned up in ~wxApp
-        delete [] command[0] ;
-        delete [] command ;
-           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();
@@ -580,33 +573,42 @@ int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_
   delete wxTheApp;
   wxTheApp = NULL;
 
-  delete [] buf ;
-  delete [] command[0] ;
-  delete [] command ;
-
-#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
+#if (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)
   {
-    wxTrace("There were memory leaks.\n");
-    wxDebugContext::Dump();
-    wxDebugContext::PrintStatistics();
+      wxTrace("There were memory leaks.\n");
+      wxDebugContext::Dump();
+      wxDebugContext::PrintStatistics();
   }
   wxDebugContext::SetStream(NULL, NULL);
 #endif
 
   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  */
 
+//// Entry point for DLLs
+
 int wxEntry(WXHINSTANCE hInstance)
 {
   wxhInstance = (HINSTANCE) hInstance;
-  wxApp::Initialize((WXHINSTANCE) wxhInstance);
+  wxApp::Initialize();
 
   // The app may have declared a global application object, but we recommend
   // the IMPLEMENT_APP macro is used instead, which sets an initializer function
@@ -614,13 +616,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) {
@@ -643,17 +645,15 @@ int wxEntry(WXHINSTANCE hInstance)
 }
 #endif // _WINDLL
 
-// Static member initialization
+//// Static member initialization
+
 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
 
 wxApp::wxApp()
 {
   m_topWindow = NULL;
   wxTheApp = this;
-//  work_proc = NULL ;
   m_className = "";
-//  m_resourceCollection = TRUE;
-//  m_pendingCleanup = FALSE;
   m_wantDebugOutput = TRUE ;
   m_appName = "";
   argc = 0;
@@ -667,6 +667,17 @@ wxApp::wxApp()
   m_auto3D = TRUE;
 }
 
+wxApp::~wxApp()
+{
+  // Delete command-line args
+  int i;
+  for (i = 0; i < argc; i++)
+  {
+    delete[] argv[i];
+  }
+  delete[] argv;
+}
+
 bool wxApp::Initialized()
 {
 #ifndef _WINDLL
@@ -824,40 +835,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->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()
@@ -878,59 +889,22 @@ void wxApp::DeletePendingObjects()
   }
 }
 
-/*
-// Free up font objects that are not being used at present.
-bool wxApp::DoResourceCleanup()
+void wxApp::OnEndSession(wxCloseEvent& event)
 {
-//  wxDebugMsg("ResourceCleanup\n");
+    if (GetTopWindow())
+        GetTopWindow()->Close(TRUE);
+}
 
-  if (wxTheFontList)
-  {
-    wxNode *node = wxTheFontList->First();
-    while (node)
-    {
-      wxGDIObject *obj = (wxGDIObject *)node->Data();
-      if ((obj->GetResourceHandle() != 0) && (obj->GetResourceUsage() == 0))
-      {
-//        wxDebugMsg("Freeing font %ld (GDI object %d)\n", (long)obj, (int)obj->GetResourceHandle());
-        obj->FreeResource();
-      }
-      node = node->Next();
-    }
-  }
-  if (wxThePenList)
-  {
-    wxNode *node = wxThePenList->First();
-    while (node)
-    {
-      wxGDIObject *obj = (wxGDIObject *)node->Data();
-      if ((obj->GetResourceHandle() != 0) && (obj->GetResourceUsage() == 0))
-      {
-//        wxDebugMsg("Freeing pen %ld (GDI object %d)\n", (long)obj, (int)obj->GetResourceHandle());
-        obj->FreeResource();
-      }
-      node = node->Next();
-    }
-  }
-  if (wxTheBrushList)
-  {
-    wxNode *node = wxTheBrushList->First();
-    while (node)
+// 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())
     {
-      wxGDIObject *obj = (wxGDIObject *)node->Data();
-      if ((obj->GetResourceHandle() != 0) && (obj->GetResourceUsage() == 0))
-      {
-//        wxDebugMsg("Freeing brush %ld (GDI object %d)\n", (long)obj, (int)obj->GetResourceHandle());
-        obj->FreeResource();
-      }
-      node = node->Next();
+        if (!GetTopWindow()->Close(!event.CanVeto()))
+            event.Veto(TRUE);
     }
-  }
-
-  SetPendingCleanup(FALSE);
-  return FALSE;
 }
-*/
 
 wxLog* wxApp::CreateLogTarget()
 {
@@ -961,30 +935,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;
@@ -1013,14 +987,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
-
-#undef IN_WX_MAIN_CPP
-