]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
Fixed three mouse event bugs
[wxWidgets.git] / src / msw / app.cpp
index cb88395f1a4cecf5d183fb24bb8246d68a93e3e3..76458c15a63439c7c5eac1590c041bf1b275d126 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
-  #pragma implementation "app.h"
+#pragma implementation "app.h"
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #if defined(__BORLANDC__)
-  #pragma hdrstop
+#pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
 #endif
 
 #include "wx/msw/private.h"
-#include "wx/postscrp.h"
 #include "wx/log.h"
 #include "wx/module.h"
 
-#if USE_WX_RESOURCES
+#if wxUSE_WX_RESOURCES
   #include "wx/resource.h"
 #endif
 
   #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)
+// 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
+
+#ifdef wxUSE_VC_CRTDBG
   // VC++ uses this macro as debug/release mode indicator
   #ifndef _DEBUG
     #define _DEBUG
@@ -61,7 +66,6 @@
 
   #include <crtdbg.h>
 #endif
-*/
 
 extern char *wxBuffer;
 extern char *wxOsVersion;
@@ -98,6 +102,8 @@ LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
 
   BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
       EVT_IDLE(wxApp::OnIdle)
+      EVT_END_SESSION(wxApp::OnEndSession)
+      EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
   END_EVENT_TABLE()
 #endif
 
@@ -111,54 +117,34 @@ long wxApp::sm_lastMessageTime = 0;
 
 bool wxApp::Initialize()
 {
-  wxBuffer = new char[1500];
+    wxBuffer = new char[1500];
 
-/*
-  #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
-    #if defined(_WINDLL)
-      streambuf* sBuf = NULL;
-    #else  // EXE
-      streambuf* sBuf = new wxDebugStreamBuf;
-    #endif // DLL
+    wxClassInfo::InitializeClasses();
 
-    ostream* oStr = new ostream(sBuf) ;
-    wxDebugContext::SetStream(oStr, sBuf);
-  #endif  // USE_MEMORY_TRACING
-
-  wxClassInfo::InitializeClasses();
-
-  #if USE_RESOURCES
+#if wxUSE_RESOURCES
     wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
-  #endif
+#endif
 
-  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
-  wxTheColourDatabase->Initialize();
+    wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
+    wxTheColourDatabase->Initialize();
 
-  wxInitializeStockLists();
-  wxInitializeStockObjects();
+    wxInitializeStockLists();
+    wxInitializeStockObjects();
 
-  #if USE_WX_RESOURCES
+#if wxUSE_WX_RESOURCES
     wxInitializeResourceSystem();
-  #endif
-
-  // For PostScript printing
-  #if USE_POSTSCRIPT
-    wxInitializePrintSetupData();
-    wxThePrintPaperDatabase = new wxPrintPaperDatabase;
-    wxThePrintPaperDatabase->CreateDatabase();
-  #endif
+#endif
 
-  wxBitmap::InitStandardHandlers();
+    wxBitmap::InitStandardHandlers();
 
-  #if defined(__WIN95__)
+#if defined(__WIN95__)
     InitCommonControls();
     gs_hRichEdit = LoadLibrary("RICHED32.DLL");
 
@@ -166,60 +152,75 @@ bool wxApp::Initialize()
     {
       wxMessageBox("Could not initialise Rich Edit DLL");
     }
-  #endif
+#endif
+
+    int iMsg = 96;
+                       
+   // for OLE, enlarge message queue to be as large as possible
+   while (!SetMessageQueue(iMsg) && (iMsg -= 8));
 
-  #if  defined(WX_DRAG_DROP)
+/*
+    DWORD dwOleVer;
+    dwOleVer = CoBuildVersion();
+       
+    // check the OLE library version
+    if (rmm != HIWORD(dwOleVer))
+    {
+        wxMessageBox("Incorrect version of OLE libraries.");
+        return FALSE;
+    }
+*/
+       
     // we need to initialize OLE library
     if ( FAILED(::OleInitialize(NULL)) )
       wxFatalError(_("Cannot initialize OLE"));
-  #endif
 
-  #if CTL3D
+#if CTL3D
     if (!Ctl3dRegister(wxhInstance))
       wxFatalError("Cannot register CTL3D");
 
     Ctl3dAutoSubclass(wxhInstance);
-  #endif
+#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
+#if wxUSE_PENWINDOWS
     wxRegisterPenWin();
-  #endif
+#endif
 
-  wxWinHandleList = new wxList(wxKEY_INTEGER);
+    wxWinHandleList = new wxList(wxKEY_INTEGER);
 
-  // This is to foil optimizations in Visual C++ that
-  // throw out dummy.obj.
-  #if (_MSC_VER >= 800) && !defined(WXMAKINGDLL)
+    // 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
+#endif
 
-  wxSetKeyboardHook(TRUE);
+    wxSetKeyboardHook(TRUE);
 
-  wxModule::RegisterModules();
-  if (!wxModule::InitializeModules())
-    return FALSE;
-  return TRUE;
+    wxModule::RegisterModules();
+    if (!wxModule::InitializeModules())
+        return FALSE;
+    return TRUE;
 }
 
 //// RegisterWindowClasses
@@ -350,82 +351,76 @@ bool wxApp::RegisterWindowClasses()
 
 //// Convert Windows to argc, argv style
 
-// 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??
-
-  int count = 0;
-  char *buf = new char[strlen(lpCmdLine) + 1];
+    wxStringList args;
 
-  /* 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[260]; // 260 is MAX_PATH value from windef.h
-  ::GetModuleFileName(wxhInstance, name, WXSIZEOF(name));
+    // 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);
+    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)
-  {
-    if ( count == WXSIZEOF(command) )
+    // Break up string
+    // Treat strings enclosed in double-quotes as single arguments
+    int i = 0;
+    int len = cmdLine.Length();
+    while (i < len)
     {
-      wxFAIL_MSG("too many command line args.");
-      break;
-    }
+        // Skip whitespace
+        while ((i < len) && isspace(cmdLine.GetChar(i)))
+            i ++;
 
-    while ( *str && isspace(*str) )  // skip whitespace
-      str++;
-
-    if (*str == '"')
-    {
-      str++;
-      command[count++] = str;
-      while (*str && *str != '"')
-        str++;
+        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 ++;
+            }
+        }
     }
-    else if (*str)
+
+    wxTheApp->argv = new char*[count + 1];
+    for (i = 0; i < count; i++)
     {
-      command[count++] = str;
-      while (*str && !isspace(*str))
-        str++;
+        wxString arg(args[i]);
+        wxTheApp->argv[i] = copystring((const char*)arg);
     }
-    if (*str)
-      *str++ = '\0';
-  }
-
-  wxTheApp->argv = new char*[count + 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 [] command[i];
-  }
-
-  delete [] command;
-  delete [] buf;
+    wxTheApp->argv[count] = NULL; // argv[] is a NULL-terminated list
+    wxTheApp->argc = count;
 }
 
 //// Cleans up any wxWindows internal structures left lying around
@@ -435,7 +430,7 @@ void wxApp::CleanUp()
   //// COMMON CLEANUP
   wxModule::CleanUpModules();
 
-#if USE_WX_RESOURCES
+#if wxUSE_WX_RESOURCES
   wxCleanUpResourceSystem();
 
 //  wxDefaultResourceTable->ClearTable();
@@ -456,12 +451,6 @@ void wxApp::CleanUp()
   delete wxTheColourDatabase;
   wxTheColourDatabase = NULL;
 
-#if USE_POSTSCRIPT
-  wxInitializePrintSetupData(FALSE);
-  delete wxThePrintPaperDatabase;
-  wxThePrintPaperDatabase = NULL;
-#endif
-
   wxBitmap::CleanUpHandlers();
 
   delete[] wxBuffer;
@@ -476,7 +465,7 @@ void wxApp::CleanUp()
     FreeLibrary(gs_hRichEdit);
 #endif
 
-#if USE_PENWINDOWS
+#if wxUSE_PENWINDOWS
   wxCleanUpPenWin();
 #endif
 
@@ -497,9 +486,7 @@ void wxApp::CleanUp()
   if ( wxDisableButtonBrush )
     ::DeleteObject( wxDisableButtonBrush ) ;
 
-#if     defined(WX_DRAG_DROP)
   ::OleUninitialize();
-#endif
 
 #if CTL3D
   Ctl3dUnregister(wxhInstance);
@@ -510,6 +497,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);
@@ -525,7 +529,7 @@ int wxEntry(WXHINSTANCE hInstance,
             bool enterLoop)
 {
 #ifndef __WXDEBUG__ // take everything into a try-except block in release build
-  __try {
+  try {
 #endif
 
   wxhInstance = (HINSTANCE) hInstance;
@@ -584,29 +588,19 @@ int wxEntry(WXHINSTANCE hInstance,
   }
 
   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 ) {
+  except ( EXCEPTION_EXECUTE_HANDLER ) {
     /*
     if ( wxTheApp )
       wxTheApp->OnFatalException();
@@ -691,7 +685,7 @@ wxApp::~wxApp()
   {
     delete[] argv[i];
   }
-  delete argv;
+  delete[] argv;
 }
 
 bool wxApp::Initialized()
@@ -870,12 +864,12 @@ bool wxApp::SendIdleEvents(wxWindow* win)
 
   wxIdleEvent event;
   event.SetEventObject(win);
-  win->ProcessEvent(event);
+  win->GetEventHandler()->ProcessEvent(event);
 
   if (event.MoreRequested())
     needMore = TRUE;
 
-  wxNode* node = win->GetChildren()->First();
+  wxNode* node = win->GetChildren().First();
   while (node)
   {
     wxWindow* win = (wxWindow*) node->Data();
@@ -905,6 +899,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;