]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/app.cpp
fixed wxComboBox sizing problem again
[wxWidgets.git] / src / msw / app.cpp
index 7d642fc7e2d082b7b3ae521c2e580f80561a2588..ed4d7367887739ba8cb9c71fb08307ef66151cdd 100644 (file)
 // ---------------------------------------------------------------------------
 
 extern wxChar *wxBuffer;
 // ---------------------------------------------------------------------------
 
 extern wxChar *wxBuffer;
-extern wxChar *wxOsVersion;
 extern wxList *wxWinHandleList;
 extern wxList WXDLLEXPORT wxPendingDelete;
 extern void wxSetKeyboardHook(bool doIt);
 extern wxList *wxWinHandleList;
 extern wxList WXDLLEXPORT wxPendingDelete;
 extern void wxSetKeyboardHook(bool doIt);
@@ -155,6 +154,16 @@ HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
 
 LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
 
 
 LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
 
+// FIXME wxUSE_ON_FATAL_EXCEPTION is only supported for VC++ now because it
+//       needs compiler support for Win32 SEH. Others (especially Borland)
+//       probably have it too, but I'm not sure about how it works
+// JACS: get 'Cannot use __try in functions that require unwinding
+// in Unicode mode, so disabling.
+#if !defined(__VISUALC__) || defined(__WIN16__) || defined(UNICODE)
+    #undef wxUSE_ON_FATAL_EXCEPTION
+    #define wxUSE_ON_FATAL_EXCEPTION 0
+#endif // VC++
+
 #if wxUSE_ON_FATAL_EXCEPTION
     static bool gs_handleExceptions = FALSE;
 #endif
 #if wxUSE_ON_FATAL_EXCEPTION
     static bool gs_handleExceptions = FALSE;
 #endif
@@ -167,17 +176,38 @@ LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
 // wxApp
 // ---------------------------------------------------------------------------
 
 // wxApp
 // ---------------------------------------------------------------------------
 
-    IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
+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()
+BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
+    EVT_IDLE(wxApp::OnIdle)
+    EVT_END_SESSION(wxApp::OnEndSession)
+    EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
+END_EVENT_TABLE()
 
 //// Initialize
 bool wxApp::Initialize()
 {
 
 //// Initialize
 bool wxApp::Initialize()
 {
+    // the first thing to do is to check if we're trying to run an Unicode
+    // program under Win9x - if so, abort right now as it has no chance to
+    // work
+#if wxUSE_UNICODE
+    if ( wxGetOsVersion() != wxWINDOWS_NT )
+    {
+        // note that we can use MessageBoxW() as it's implemented even under
+        // Win9x - OTOH, we can't use wxGetTranslation() because the file APIs
+        // used by wxLocale are not
+        ::MessageBox
+        (
+         NULL,
+         _T("This program uses Unicode and requires Windows NT/2000.\nProgram aborted."),
+         _T("wxWindows Fatal Error"),
+         MB_ICONERROR | MB_OK
+        );
+
+        return FALSE;
+    }
+#endif // wxUSE_UNICODE
+
     // Some people may wish to use this, but
     // probably it shouldn't be here by default.
 #ifdef __WXDEBUG__
     // Some people may wish to use this, but
     // probably it shouldn't be here by default.
 #ifdef __WXDEBUG__
@@ -188,10 +218,6 @@ bool wxApp::Initialize()
 
     wxClassInfo::InitializeClasses();
 
 
     wxClassInfo::InitializeClasses();
 
-#if wxUSE_RESOURCES
-    wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
-#endif
-
 #if wxUSE_THREADS
     wxPendingEventsLocker = new wxCriticalSection;
 #endif
 #if wxUSE_THREADS
     wxPendingEventsLocker = new wxCriticalSection;
 #endif
@@ -311,7 +337,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(frame)");
+        wxLogLastError(wxT("RegisterClass(frame)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -322,7 +348,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(no redraw frame)");
+        wxLogLastError(wxT("RegisterClass(no redraw frame)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -334,7 +360,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(MDI parent)");
+        wxLogLastError(wxT("RegisterClass(MDI parent)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -345,7 +371,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(no redraw MDI parent frame)");
+        wxLogLastError(wxT("RegisterClass(no redraw MDI parent frame)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -357,7 +383,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(MDI child)");
+        wxLogLastError(wxT("RegisterClass(MDI child)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -368,7 +394,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(no redraw MDI child)");
+        wxLogLastError(wxT("RegisterClass(no redraw MDI child)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -380,7 +406,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(panel)");
+        wxLogLastError(wxT("RegisterClass(panel)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -391,7 +417,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(no redraw panel)");
+        wxLogLastError(wxT("RegisterClass(no redraw panel)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -402,7 +428,7 @@ bool wxApp::RegisterWindowClasses()
 
     if ( !RegisterClass(&wndclass) )
     {
 
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(canvas)");
+        wxLogLastError(wxT("RegisterClass(canvas)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -411,7 +437,7 @@ bool wxApp::RegisterWindowClasses()
     wndclass.style         = styleNoRedraw;
     if ( !RegisterClass(&wndclass) )
     {
     wndclass.style         = styleNoRedraw;
     if ( !RegisterClass(&wndclass) )
     {
-        wxLogLastError("RegisterClass(no redraw canvas)");
+        wxLogLastError(wxT("RegisterClass(no redraw canvas)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -575,7 +601,9 @@ void wxApp::CleanUp()
 #if wxUSE_THREADS
     delete wxPendingEventsLocker;
     // If we don't do the following, we get an apparent memory leak.
 #if wxUSE_THREADS
     delete wxPendingEventsLocker;
     // If we don't do the following, we get an apparent memory leak.
+#if wxUSE_VALIDATORS
     ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
     ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
+#endif
 #endif
 
     wxClassInfo::CleanUpClasses();
 #endif
 
     wxClassInfo::CleanUpClasses();
@@ -607,12 +635,12 @@ void wxApp::CleanUp()
 // Entry point helpers, used by wxPython
 //----------------------------------------------------------------------
 
 // Entry point helpers, used by wxPython
 //----------------------------------------------------------------------
 
-int  WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char** WXUNUSED(argv) )
+int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char** WXUNUSED(argv) )
 {
     return wxApp::Initialize();
 }
 
 {
     return wxApp::Initialize();
 }
 
-int  WXDLLEXPORT wxEntryInitGui()
+int WXDLLEXPORT wxEntryInitGui()
 {
     wxTheApp->OnInitGui();
     return 0;
 {
     wxTheApp->OnInitGui();
     return 0;
@@ -659,15 +687,6 @@ int wxEntry(WXHINSTANCE hInstance,
 
     // take everything into a try-except block to be able to call
     // OnFatalException() if necessary
 
     // take everything into a try-except block to be able to call
     // OnFatalException() if necessary
-
-    // FIXME other compilers must support Win32 SEH (structured exception
-    //       handling) too, just find the appropriate keyword in their docs!
-    //       Please note that it's _not_ the same as C++ exceptions!
-#ifndef __VISUALC__
-    #undef wxUSE_ON_FATAL_EXCEPTION
-    #define wxUSE_ON_FATAL_EXCEPTION 0
-#endif // VC++
-
 #if wxUSE_ON_FATAL_EXCEPTION
     __try {
 #endif
 #if wxUSE_ON_FATAL_EXCEPTION
     __try {
 #endif
@@ -707,15 +726,33 @@ int wxEntry(WXHINSTANCE hInstance,
 
         int retValue = 0;
 
 
         int retValue = 0;
 
-        if ( wxTheApp->OnInit() )
+        // it is common to create a modal dialog in OnInit() (to ask/notify the
+        // user about something) but it wouldn't work if we don't change the
+        // "exit on delete last frame" flag here as when this dialog is
+        // deleted, the app would terminate (it was the last top level window
+        // as the main frame wasn't created yet!), so disable this behaviour
+        // temproarily
+        bool exitOnLastFrameDelete = wxTheApp->GetExitOnFrameDelete();
+        wxTheApp->SetExitOnFrameDelete(FALSE);
+
+        // init the app
+        retValue = wxTheApp->OnInit() ? 0 : -1;
+
+        // restore the old flag value
+        wxTheApp->SetExitOnFrameDelete(exitOnLastFrameDelete);
+
+        if ( retValue == 0 )
         {
             if ( enterLoop )
             {
         {
             if ( enterLoop )
             {
+                // run the main loop
                 retValue = wxTheApp->OnRun();
             }
             else
                 retValue = wxTheApp->OnRun();
             }
             else
-                // We want to initialize, but not run or exit immediately.
+            {
+                // we want to initialize, but not run or exit immediately.
                 return 1;
                 return 1;
+            }
         }
         //else: app initialization failed, so we skipped OnRun()
 
         }
         //else: app initialization failed, so we skipped OnRun()
 
@@ -747,14 +784,10 @@ int wxEntry(WXHINSTANCE hInstance,
     __except ( gs_handleExceptions ? EXCEPTION_EXECUTE_HANDLER
                                    : EXCEPTION_CONTINUE_SEARCH ) {
         if ( wxTheApp )
     __except ( gs_handleExceptions ? EXCEPTION_EXECUTE_HANDLER
                                    : EXCEPTION_CONTINUE_SEARCH ) {
         if ( wxTheApp )
+        {
+           // give the user a chance to do something special about this
            wxTheApp->OnFatalException();
            wxTheApp->OnFatalException();
-
-        // using wxLog would be unsafe here
-        ::MessageBox(NULL,
-                     _("Unrecoverable program error detected: "
-                     " the application will terminate."),
-                     _("Fatal Error"),
-                     MB_APPLMODAL | MB_ICONSTOP | MB_OK);
+        }
 
         ::ExitProcess(3); // the same exit code as abort()
 
 
         ::ExitProcess(3); // the same exit code as abort()
 
@@ -867,7 +900,7 @@ bool wxApp::DoMessage()
     else if ( rc == -1 )
     {
         // should never happen, but let's test for it nevertheless
     else if ( rc == -1 )
     {
         // should never happen, but let's test for it nevertheless
-        wxLogLastError("GetMessage");
+        wxLogLastError(wxT("GetMessage"));
     }
     else
     {
     }
     else
     {
@@ -1022,10 +1055,17 @@ bool wxApp::ProcessMessage(WXMSG *wxmsg)
     // Try translations first; find the youngest window with
     // a translation table.
     wxWindow *wnd;
     // Try translations first; find the youngest window with
     // a translation table.
     wxWindow *wnd;
+
     for ( wnd = wndThis; wnd; wnd = wnd->GetParent() )
     {
         if ( wnd->MSWTranslateMessage(wxmsg) )
             return TRUE;
     for ( wnd = wndThis; wnd; wnd = wnd->GetParent() )
     {
         if ( wnd->MSWTranslateMessage(wxmsg) )
             return TRUE;
+
+        // stop at first top level window, i.e. don't try to process the key
+        // strokes originating in a dialog using the accelerators of the parent
+        // frame - this doesn't make much sense
+        if ( wnd->IsTopLevel() )
+            break;
     }
 
     // Anyone for a non-translation message? Try youngest descendants first.
     }
 
     // Anyone for a non-translation message? Try youngest descendants first.
@@ -1175,7 +1215,7 @@ int wxApp::GetComCtl32Version()
             // try to use DllGetVersion() if available in _headers_
             #ifdef DLLVER_PLATFORM_WINDOWS // defined in shlwapi.h
                 DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)
             // try to use DllGetVersion() if available in _headers_
             #ifdef DLLVER_PLATFORM_WINDOWS // defined in shlwapi.h
                 DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)
-                    ::GetProcAddress(hModuleComCtl32, _T("DllGetVersion"));
+                    ::GetProcAddress(hModuleComCtl32, "DllGetVersion");
                 if ( pfnDllGetVersion )
                 {
                     DLLVERSIONINFO dvi;
                 if ( pfnDllGetVersion )
                 {
                     DLLVERSIONINFO dvi;
@@ -1204,11 +1244,7 @@ int wxApp::GetComCtl32Version()
                     FARPROC theProc = ::GetProcAddress
                                         (
                                          hModuleComCtl32,
                     FARPROC theProc = ::GetProcAddress
                                         (
                                          hModuleComCtl32,
-#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x520)
                                          "InitCommonControlsEx"
                                          "InitCommonControlsEx"
-#else
-                                         _T("InitCommonControlsEx")
-#endif
                                         );
 
                     if ( !theProc )
                                         );
 
                     if ( !theProc )
@@ -1223,11 +1259,7 @@ int wxApp::GetComCtl32Version()
                         theProc = ::GetProcAddress
                                     (
                                      hModuleComCtl32,
                         theProc = ::GetProcAddress
                                     (
                                      hModuleComCtl32,
-#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x520)
                                      "InitializeFlatSB"
                                      "InitializeFlatSB"
-#else
-                                     _T("InitializeFlatSB")
-#endif
                                     );
                         if ( !theProc )
                         {
                                     );
                         if ( !theProc )
                         {
@@ -1256,12 +1288,22 @@ void wxExit()
 }
 
 // Yield to incoming messages
 }
 
 // Yield to incoming messages
+
+static bool gs_inYield = FALSE;
+
 bool wxYield()
 {
     // disable log flushing from here because a call to wxYield() shouldn't
     // normally result in message boxes popping up &c
     wxLog::Suspend();
 
 bool wxYield()
 {
     // disable log flushing from here because a call to wxYield() shouldn't
     // normally result in message boxes popping up &c
     wxLog::Suspend();
 
+#ifdef __WXDEBUG__
+    if (gs_inYield)
+        wxFAIL_MSG( wxT("wxYield called recursively" ) );
+#endif
+
+    gs_inYield = TRUE;
+
     // we don't want to process WM_QUIT from here - it should be processed in
     // the main event loop in order to stop it
     MSG msg;
     // we don't want to process WM_QUIT from here - it should be processed in
     // the main event loop in order to stop it
     MSG msg;
@@ -1283,9 +1325,20 @@ bool wxYield()
     // let the logs be flashed again
     wxLog::Resume();
 
     // let the logs be flashed again
     wxLog::Resume();
 
+    gs_inYield = FALSE;
+
     return TRUE;
 }
 
     return TRUE;
 }
 
+// Yield to incoming messages; but fail silently if recursion is detected.
+bool wxYieldIfNeeded()
+{
+    if (gs_inYield)
+        return FALSE;
+
+    return wxYield();
+}
+
 bool wxHandleFatalExceptions(bool doit)
 {
 #if wxUSE_ON_FATAL_EXCEPTION
 bool wxHandleFatalExceptions(bool doit)
 {
 #if wxUSE_ON_FATAL_EXCEPTION
@@ -1295,7 +1348,8 @@ bool wxHandleFatalExceptions(bool doit)
     return TRUE;
 #else
     wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to sue this function"));
     return TRUE;
 #else
     wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to sue this function"));
-
+       
+       (void)doit;
     return FALSE;
 #endif
 }
     return FALSE;
 #endif
 }
@@ -1316,7 +1370,7 @@ void wxWakeUpIdle()
         if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) )
         {
             // should never happen
         if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) )
         {
             // should never happen
-            wxLogLastError("PostMessage(WM_NULL)");
+            wxLogLastError(wxT("PostMessage(WM_NULL)"));
         }
     }
 }
         }
     }
 }