]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
somehow log target wasn't being created automatically anymore. Restored.
[wxWidgets.git] / src / msw / app.cpp
index 4c9218cb884be109906f1e7dfd9836539df64875..cb88395f1a4cecf5d183fb24bb8246d68a93e3e3 100644 (file)
@@ -6,34 +6,33 @@
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
-#pragma implementation "app.h"
+  #pragma implementation "app.h"
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
-#define IN_WX_MAIN_CPP
 #include "wx/wxprec.h"
 
 #if defined(__BORLANDC__)
-#pragma hdrstop
+  #pragma hdrstop
 #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/module.h"
 
 #if USE_WX_RESOURCES
-#include "wx/resource.h"
+  #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++
+/* This still doesn't work for me, Vadim.
+#if defined(__WXDEBUG__) && defined(_MSC_VER)
+  // VC++ uses this macro as debug/release mode indicator
+  #ifndef _DEBUG
+    #define _DEBUG
+  #endif
+
+  #include <crtdbg.h>
+#endif
+*/
+
 extern char *wxBuffer;
 extern char *wxOsVersion;
 extern wxList *wxWinHandleList;
@@ -59,10 +70,11 @@ extern wxList wxPendingDelete;
 extern void wxSetKeyboardHook(bool doIt);
 extern wxCursor *g_globalCursor;
 
-HANDLE wxhInstance = 0;
+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";
@@ -82,54 +94,102 @@ 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)
+  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(WXHANDLE instance)
+//// Initialize
+
+bool wxApp::Initialize()
 {
-  HANDLE hInstance = (HANDLE)instance;
+  wxBuffer = new char[1500];
 
-  CommonInit();
+/*
+  #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 && USE_MEMORY_TRACING) || USE_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  // USE_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 USE_RESOURCES
+    wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
+  #endif
 
-  Ctl3dAutoSubclass(hInstance);
-#endif
+  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
+  wxTheColourDatabase->Initialize();
 
-  wxSTD_FRAME_ICON = LoadIcon(hInstance, "wxSTD_FRAME");
-  wxSTD_MDIPARENTFRAME_ICON = LoadIcon(hInstance, "wxSTD_MDIPARENTFRAME");
-  wxSTD_MDICHILDFRAME_ICON = LoadIcon(hInstance, "wxSTD_MDICHILDFRAME");
+  wxInitializeStockLists();
+  wxInitializeStockObjects();
+
+  #if USE_WX_RESOURCES
+    wxInitializeResourceSystem();
+  #endif
+
+  // For PostScript printing
+  #if USE_POSTSCRIPT
+    wxInitializePrintSetupData();
+    wxThePrintPaperDatabase = new wxPrintPaperDatabase;
+    wxThePrintPaperDatabase->CreateDatabase();
+  #endif
+
+  wxBitmap::InitStandardHandlers();
+
+  #if defined(__WIN95__)
+    InitCommonControls();
+    gs_hRichEdit = LoadLibrary("RICHED32.DLL");
+
+    if (gs_hRichEdit == NULL)
+    {
+      wxMessageBox("Could not initialise Rich Edit DLL");
+    }
+  #endif
 
-  wxDEFAULT_FRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_FRAME");
-  wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_MDIPARENTFRAME");
-  wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_MDICHILDFRAME");
+  #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");
+
+    Ctl3dAutoSubclass(wxhInstance);
+  #endif
+
+  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();
 
@@ -137,22 +197,23 @@ bool wxApp::Initialize(WXHANDLE 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 USE_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();
@@ -161,7 +222,9 @@ bool wxApp::Initialize(WXHANDLE instance)
   return TRUE;
 }
 
-bool wxApp::RegisterWindowClasses(void)
+//// RegisterWindowClasses
+
+bool wxApp::RegisterWindowClasses()
 {
 ///////////////////////////////////////////////////////////////////////
 // Register the frame window class.
@@ -178,7 +241,7 @@ bool wxApp::RegisterWindowClasses(void)
 //  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;
 
@@ -206,7 +269,7 @@ bool wxApp::RegisterWindowClasses(void)
   if (!RegisterClass( &wndclass1 ))
   {
 //    wxFatalError("Can't register MDI Frame window class");
-//     return FALSE;
+//  return FALSE;
   }
 
 ///////////////////////////////////////////////////////////////////////
@@ -248,7 +311,7 @@ bool wxApp::RegisterWindowClasses(void)
   wndclass2.hIcon         = NULL;
   wndclass2.hCursor       = NULL;
 //  wndclass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1) ;
-  wndclass2.hbrBackground = GetStockObject( LTGRAY_BRUSH );
+  wndclass2.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH );
   wndclass2.lpszMenuName  = NULL;
   wndclass2.lpszClassName = wxPanelClassName;
   if (!RegisterClass( &wndclass2 ))
@@ -263,9 +326,9 @@ bool wxApp::RegisterWindowClasses(void)
   memset(&wndclass3, 0, sizeof(WNDCLASS));   // start with NULL defaults
   // Use CS_OWNDC to avoid messing about restoring the context
   // for every graphic operation.
-//  wndclass3.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS ; 
+//  wndclass3.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS ;
   // wxWin 2.0
-  wndclass3.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; 
+  wndclass3.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
   wndclass3.lpfnWndProc   = (WNDPROC)wxWndProc;
   wndclass3.cbClsExtra    = 0;
   wndclass3.cbWndExtra    = sizeof( DWORD ); // was 4
@@ -285,121 +348,99 @@ bool wxApp::RegisterWindowClasses(void)
   return TRUE;
 }
 
-// Cleans up any wxWindows internal structures left lying around
-void wxApp::CleanUp(void)
-{
-  wxModule::CleanUpModules();
-
-  CommonCleanUp();
-
-  wxSetKeyboardHook(FALSE);
-
-#ifdef __WIN95__
-  if (gs_hRichEdit != NULL)
-    FreeLibrary(gs_hRichEdit);
-#endif
-
-#if USE_PENWINDOWS
-  wxCleanUpPenWin();
-#endif
+//// Convert Windows to argc, argv style
 
-  if (wxSTD_FRAME_ICON)
-    DestroyIcon(wxSTD_FRAME_ICON);
-  if (wxSTD_MDICHILDFRAME_ICON)
-    DestroyIcon(wxSTD_MDICHILDFRAME_ICON);
-  if (wxSTD_MDIPARENTFRAME_ICON)
-    DestroyIcon(wxSTD_MDIPARENTFRAME_ICON);
-
-  if (wxDEFAULT_FRAME_ICON)
-    DestroyIcon(wxDEFAULT_FRAME_ICON);
-  if (wxDEFAULT_MDICHILDFRAME_ICON)
-    DestroyIcon(wxDEFAULT_MDICHILDFRAME_ICON);
-  if (wxDEFAULT_MDIPARENTFRAME_ICON)
-    DestroyIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
-
-  if ( wxDisableButtonBrush )
-    ::DeleteObject( wxDisableButtonBrush ) ;
+// FIXME this code should be rewritten (use wxArrayString instead...)
+void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
+{
+  // Split command line into tokens, as in usual main(argc, argv)
+  char **command = new char*[50]; // VZ: sure? why not 25 or 73 and a half??
 
-#if     defined(WX_DRAG_DROP)
-  ::OleUninitialize();
-#endif
+  int count = 0;
+  char *buf = new char[strlen(lpCmdLine) + 1];
 
-#if CTL3D
-  Ctl3dUnregister(wxhInstance);
-#endif
+  /* Model independent strcpy */
+  int i;
+  for (i = 0; (buf[i] = lpCmdLine[i]) != 0; i++)
+  {
+    /* loop */;
+  }
 
-  if (wxWinHandleList)
-    delete wxWinHandleList ;
-    
-  // do it as the very last thing because everything else can log messages
-  delete wxLog::SetActiveTarget(NULL);
-}
+  // Get application name
+  char name[260]; // 260 is MAX_PATH value from windef.h
+  ::GetModuleFileName(wxhInstance, name, WXSIZEOF(name));
 
-void wxApp::CommonInit(void)
-{
-#ifdef __WINDOWS__
-  wxBuffer = new char[1500];
-#else
-  wxBuffer = new char[BUFSIZ + 512];
+  // 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
 
-  wxClassInfo::InitializeClasses();
-
-#ifdef __X__
-  wxTheFontNameDirectory.Initialize();
-#endif
+  strcpy(name, wxFileNameFromPath(name));
+  wxStripExtension(name);
+  wxTheApp->SetAppName(name);
 
-#if defined(__X__) && USE_RESOURCES
-  // Read standard font names from .Xdefaults
-
-  extern char *wxDecorativeFontName;
-  extern char *wxRomanFontName;
-  extern char *wxModernFontName;
-  extern char *wxSwissFontName;
-  extern char *wxScriptFontName;
-  extern char *wxTeletypeFontName;
-  extern char *wxDefaultFontName;
-
-  (void) wxGetResource("wxWindows", "defaultFamily", &wxDefaultFontName);
-  (void) wxGetResource("wxWindows", "decorativeFamily", &wxDecorativeFontName);
-  (void) wxGetResource("wxWindows", "romanFamily", &wxRomanFontName);
-  (void) wxGetResource("wxWindows", "modernFamily", &wxModernFontName);
-  (void) wxGetResource("wxWindows", "swissFamily", &wxSwissFontName);
-  (void) wxGetResource("wxWindows", "scriptFamily", &wxScriptFontName);
-  (void) wxGetResource("wxWindows", "teletypeFamily", &wxTeletypeFontName);
-#endif
+  /* Break up string */
+  // Treat strings enclosed in double-quotes as single arguments
+  char* str = buf;
+  while (*str)
+  {
+    if ( count == WXSIZEOF(command) )
+    {
+      wxFAIL_MSG("too many command line args.");
+      break;
+    }
 
-#if USE_RESOURCES
-  (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
-#endif
+    while ( *str && isspace(*str) )  // skip whitespace
+      str++;
 
-  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
-  wxTheColourDatabase->Initialize();
-  wxInitializeStockObjects();
+    if (*str == '"')
+    {
+      str++;
+      command[count++] = str;
+      while (*str && *str != '"')
+        str++;
+    }
+    else if (*str)
+    {
+      command[count++] = str;
+      while (*str && !isspace(*str))
+        str++;
+    }
+    if (*str)
+      *str++ = '\0';
+  }
 
-#if USE_WX_RESOURCES
-  wxInitializeResourceSystem();
-#endif
+  wxTheApp->argv = new char*[count + 1];
+  wxTheApp->argv[count] = NULL; /* argv[] is NULL terminated list! */
+  wxTheApp->argc = count;
 
-  // For PostScript printing
-#if USE_POSTSCRIPT
-  wxInitializePrintSetupData();
-  wxThePrintPaperDatabase = new wxPrintPaperDatabase;
-  wxThePrintPaperDatabase->CreateDatabase();
-#endif
+  for (i = 0; i < count; i++)
+  {
+    wxTheApp->argv[i] = copystring(command[i]);
 
-  wxBitmap::InitStandardHandlers();
+    delete [] command[i];
+  }
 
-  g_globalCursor = new wxCursor;
+  delete [] command;
+  delete [] buf;
 }
 
-void wxApp::CommonCleanUp(void)
+//// Cleans up any wxWindows internal structures left lying around
+
+void wxApp::CleanUp()
 {
+  //// COMMON CLEANUP
+  wxModule::CleanUpModules();
+
 #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
@@ -410,17 +451,7 @@ void wxApp::CommonCleanUp(void)
   wxDeleteStockObjects() ;
 
   // Destroy all GDI lists, etc.
-  delete wxTheBrushList;
-  wxTheBrushList = NULL;
-
-  delete wxThePenList;
-  wxThePenList = NULL;
-
-  delete wxTheFontList;
-  wxTheFontList = NULL;
-
-  delete wxTheBitmapList;
-  wxTheBitmapList = NULL;
+  wxDeleteStockLists();
 
   delete wxTheColourDatabase;
   wxTheColourDatabase = NULL;
@@ -435,192 +466,165 @@ void wxApp::CommonCleanUp(void)
 
   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)
-{
-  wxhInstance = (HINSTANCE) hInstance;
+  //// WINDOWS-SPECIFIC CLEANUP
 
-#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
+  wxSetKeyboardHook(FALSE);
 
-#if !defined(_WINDLL)
-  streambuf* sBuf = new wxDebugStreamBuf;
-#else
-  streambuf* sBuf = NULL;
+#ifdef __WIN95__
+  if (gs_hRichEdit != NULL)
+    FreeLibrary(gs_hRichEdit);
 #endif
-  ostream* oStr = new ostream(sBuf) ;
-  wxDebugContext::SetStream(oStr, sBuf);
 
+#if USE_PENWINDOWS
+  wxCleanUpPenWin();
 #endif
 
-  if (!wxApp::Initialize((WXHINSTANCE) wxhInstance))
-    return 0;
+  if (wxSTD_FRAME_ICON)
+    DestroyIcon(wxSTD_FRAME_ICON);
+  if (wxSTD_MDICHILDFRAME_ICON)
+    DestroyIcon(wxSTD_MDICHILDFRAME_ICON);
+  if (wxSTD_MDIPARENTFRAME_ICON)
+    DestroyIcon(wxSTD_MDIPARENTFRAME_ICON);
 
-  // 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.
-  if (!wxTheApp)
-  {
-       if (!wxApp::GetInitializerFunction())
-       {
-       MessageBox(NULL, "No initializer - use IMPLEMENT_APP macro.", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
-               return 0;
-       }
+  if (wxDEFAULT_FRAME_ICON)
+    DestroyIcon(wxDEFAULT_FRAME_ICON);
+  if (wxDEFAULT_MDICHILDFRAME_ICON)
+    DestroyIcon(wxDEFAULT_MDICHILDFRAME_ICON);
+  if (wxDEFAULT_MDIPARENTFRAME_ICON)
+    DestroyIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
 
-       wxTheApp = (* wxApp::GetInitializerFunction()) ();
-  }
+  if ( wxDisableButtonBrush )
+    ::DeleteObject( wxDisableButtonBrush ) ;
 
-  if (!wxTheApp) {
-    MessageBox(NULL, "You have to define an instance of wxApp!", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
-    return 0;
-  }
+#if     defined(WX_DRAG_DROP)
+  ::OleUninitialize();
+#endif
 
-  // 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
+#if CTL3D
+  Ctl3dUnregister(wxhInstance);
+#endif
 
-  /* Model independent strcpy */
-  int i;
-  for (i = 0; (buf[i] = m_lpCmdLine[i]) != 0; i++)
-  {
-    /* loop */;
-  }
+  if (wxWinHandleList)
+    delete wxWinHandleList ;
 
-  // Get application name
-  char name[200];
-  ::GetModuleFileName(wxhInstance, name, 199);
+  wxClassInfo::CleanUpClasses();
 
-  // 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
+  // do it as the very last thing because everything else can log messages
+  wxLog::DontCreateOnDemand();
+  delete wxLog::SetActiveTarget(NULL);
+}
 
-  strcpy(name, wxFileNameFromPath(name));
-  wxStripExtension(name);
-  wxTheApp->SetAppName(name);
+#if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
 
-  /* 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! */
+//// Main wxWindows entry point
+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
 
-  wxTheApp->argc = count;
-  wxTheApp->argv = command;
-  wxTheApp->m_nCmdShow = nCmdShow;
+  wxhInstance = (HINSTANCE) hInstance;
 
-  // GUI-specific initialisation. In fact on Windows we don't have any,
-  // but this call is provided for compatibility across platforms.
-  wxTheApp->OnInitGui() ;
+  if (!wxApp::Initialize())
+    return 0;
 
-  if (!wxTheApp->OnInit())
+  // create the application object or ensure that one already exists
+  if (!wxTheApp)
   {
-       wxTheApp->DeletePendingObjects();
-        wxTheApp->OnExit();
-        wxApp::CleanUp();
+    // 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." );
 
-        delete wxTheApp;
-        wxTheApp = NULL;
+    wxTheApp = (*wxApp::GetInitializerFunction()) ();
+  }
 
-        delete [] buf ;
+  wxCHECK_MSG( wxTheApp, 0, "You have to define an instance of wxApp!" );
 
-        // TODO: This should really be cleaned up in ~wxApp
-        delete [] command[0] ;
-        delete [] command ;
-           return 0;
-  }
+  // save the WinMain() parameters
+  wxTheApp->ConvertToStandardCommandArgs(lpCmdLine);
+  wxTheApp->m_nCmdShow = nCmdShow;
 
-  if (!enterLoop)
-       return 0;
+  // GUI-specific initialisation. In fact on Windows we don't have any,
+  // but this call is provided for compatibility across platforms.
+  wxTheApp->OnInitGui() ;
 
-  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();
+      }
   }
-*/
-
-  retValue = wxTheApp->OnRun();
+  //else: app initialization failed, so we skipped 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;
 
-  delete [] buf ;
-  delete [] command[0] ;
-  delete [] command ;
-
-#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
+#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();
+      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
@@ -628,13 +632,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) {
@@ -657,33 +661,40 @@ int wxEntry(WXHINSTANCE hInstance)
 }
 #endif // _WINDLL
 
-// Static member initialization
+//// Static member initialization
+
 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
 
-wxApp::wxApp(void)
+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;
   argv = NULL;
-#ifdef __WINDOWS__
+#ifdef __WXMSW__
   m_printMode = wxPRINT_WINDOWS;
 #else
   m_printMode = wxPRINT_POSTSCRIPT;
 #endif
-//  work_proc = NULL;
   m_exitOnFrameDelete = TRUE;
-//  m_showOnInit = TRUE;
   m_auto3D = TRUE;
 }
 
-bool wxApp::Initialized(void)
+wxApp::~wxApp()
+{
+  // Delete command-line args
+  int i;
+  for (i = 0; i < argc; i++)
+  {
+    delete[] argv[i];
+  }
+  delete argv;
+}
+
+bool wxApp::Initialized()
 {
 #ifndef _WINDLL
   if (GetTopWindow())
@@ -701,13 +712,13 @@ bool wxApp::Initialized(void)
  * received.
  *
  */
-bool wxApp::DoMessage(void)
+bool wxApp::DoMessage()
 {
   if (!::GetMessage(&s_currentMsg, (HWND) NULL, 0, 0))
   {
     return FALSE;
   }
-    
+
   // Process the message
   if (!ProcessMessage((WXMSG *)&s_currentMsg))
   {
@@ -732,7 +743,7 @@ bool wxApp::DoMessage(void)
  * are processed (it'll sit in DoMessage).
  */
 
-int wxApp::MainLoop(void)
+int wxApp::MainLoop()
 {
   m_keepGoing = TRUE;
   while (m_keepGoing)
@@ -747,7 +758,7 @@ int wxApp::MainLoop(void)
 }
 
 // Returns TRUE if more time is needed.
-bool wxApp::ProcessIdle(void)
+bool wxApp::ProcessIdle()
 {
     wxIdleEvent event;
     event.SetEventObject(this);
@@ -756,17 +767,17 @@ bool wxApp::ProcessIdle(void)
     return event.MoreRequested();
 }
 
-void wxApp::ExitMainLoop(void)
+void wxApp::ExitMainLoop()
 {
   m_keepGoing = FALSE;
 }
 
-bool wxApp::Pending(void)
+bool wxApp::Pending()
 {
   return (::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0) ;
 }
 
-void wxApp::Dispatch(void)
+void wxApp::Dispatch()
 {
     if (!DoMessage())
       m_keepGoing = FALSE;
@@ -783,26 +794,29 @@ bool wxApp::ProcessMessage(WXMSG *Msg)
 
   HWND hWnd;
 
-  // Anyone for a message? Try youngest descendants first.
+  // Try translations first; find the youngest window with
+  // a translation table.
   for (hWnd = msg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
   {
     wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
     if (wnd)
     {
-       if (wnd->MSWProcessMessage(Msg))
+       if (wnd->MSWTranslateMessage(Msg))
          return TRUE;
-
-       // STOP if we've reached the top of the hierarchy!
-//       if (m_topWindow && (wnd == m_topWindow))
-//          return FALSE;
     }
   }
 
-  // TODO: Is this now obsolete, given that m_topWindow may not be defined?
-  // Does it do anything useful anyway?
-//  if (m_topWindow && m_topWindow->MSWProcessMessage(Msg))
-//     return TRUE;
-    return FALSE;
+  // Anyone for a non-translation message? Try youngest descendants first.
+  for (hWnd = msg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
+  {
+    wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
+    if (wnd)
+    {
+       if (wnd->MSWProcessMessage(Msg))
+         return TRUE;
+    }
+  }
+  return FALSE;
 }
 
 void wxApp::OnIdle(wxIdleEvent& event)
@@ -834,65 +848,52 @@ void wxApp::OnIdle(wxIdleEvent& event)
 }
 
 // Send idle event to all top-level windows
-bool wxApp::SendIdleEvents(void)
+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 ;
 }
 
-// Windows specific. Intercept keyboard input: by default,
-// route it to the active frame or dialog box.
-#if WXWIN_COMPATIBILITY == 2
-bool wxApp::OldOnCharHook(wxKeyEvent& event)
-{
-  wxWindow *win = wxGetActiveWindow();
-  if (win)
-    return win->GetEventHandler()->OldOnCharHook(event);
-  else
-    return FALSE;
-}
-#endif
-
-void wxApp::DeletePendingObjects(void)
+void wxApp::DeletePendingObjects()
 {
   wxNode *node = wxPendingDelete.First();
   while (node)
   {
     wxObject *obj = (wxObject *)node->Data();
-    
+
     delete obj;
 
     if (wxPendingDelete.Member(obj))
@@ -904,66 +905,12 @@ void wxApp::DeletePendingObjects(void)
   }
 }
 
-/*
-// Free up font objects that are not being used at present.
-bool wxApp::DoResourceCleanup(void)
-{
-//  wxDebugMsg("ResourceCleanup\n");
-
-  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)
-    {
-      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();
-    }
-  }
-
-  SetPendingCleanup(FALSE);
-  return FALSE;
-}
-*/
-
-wxLog* wxApp::CreateLogTarget(void)
+wxLog* wxApp::CreateLogTarget()
 {
     return new wxLogGui;
 }
 
-wxWindow* wxApp::GetTopWindow(void) const
+wxWindow* wxApp::GetTopWindow() const
 {
     if (m_topWindow)
         return m_topWindow;
@@ -973,14 +920,57 @@ wxWindow* wxApp::GetTopWindow(void) const
         return NULL;
 }
 
-void wxExit(void)
+int wxApp::GetComCtl32Version() const
+{
+    // have we loaded COMCTL32 yet?
+    HMODULE theModule = ::GetModuleHandle("COMCTL32");
+    int version = 0;
+
+    // if so, then we can check for the version
+    if (theModule)
+    {
+        // InitCommonControlsEx is unique to 4.7 and later
+        FARPROC theProc = ::GetProcAddress(theModule, "InitCommonControlsEx");
+
+        if (! theProc)
+        {                    // not found, must be 4.00
+      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;
+      }
+        }
+    }
+    return version;
+}
+
+void wxExit()
 {
   wxApp::CleanUp();
   FatalAppExit(0, "Fatal error: exiting");
 }
 
 // Yield to incoming messages
-bool wxYield(void)
+bool wxYield()
 {
   MSG msg;
   // We want to go back to the main message loop
@@ -996,14 +986,11 @@ bool wxYield(void)
 
 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
-