-// 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;
+// ===========================================================================
+// wxGUIAppTraits implementation
+// ===========================================================================
+
+// private class which we use to pass parameters from BeforeChildWaitLoop() to
+// AfterChildWaitLoop()
+struct ChildWaitLoopData
+{
+ ChildWaitLoopData(wxWindowDisabler *wd_, wxWindow *winActive_)
+ {
+ wd = wd_;
+ winActive = winActive_;
+ }
+
+ wxWindowDisabler *wd;
+ wxWindow *winActive;
+};
+
+void *wxGUIAppTraits::BeforeChildWaitLoop()
+{
+ /*
+ We use a dirty hack here to disable all application windows (which we
+ must do because otherwise the calls to wxYield() could lead to some very
+ unexpected reentrancies in the users code) but to avoid losing
+ focus/activation entirely when the child process terminates which would
+ happen if we simply disabled everything using wxWindowDisabler. Indeed,
+ remember that Windows will never activate a disabled window and when the
+ last childs window is closed and Windows looks for a window to activate
+ all our windows are still disabled. There is no way to enable them in
+ time because we don't know when the childs windows are going to be
+ closed, so the solution we use here is to keep one special tiny frame
+ enabled all the time. Then when the child terminates it will get
+ activated and when we close it below -- after reenabling all the other
+ windows! -- the previously active window becomes activated again and
+ everything is ok.
+ */
+ wxBeginBusyCursor();
+
+ // first disable all existing windows
+ wxWindowDisabler *wd = new wxWindowDisabler;
+
+ // then create an "invisible" frame: it has minimal size, is positioned
+ // (hopefully) outside the screen and doesn't appear on the taskbar
+ wxWindow *winActive = new wxFrame
+ (
+ wxTheApp->GetTopWindow(),
+ wxID_ANY,
+ wxEmptyString,
+ wxPoint(32600, 32600),
+ wxSize(1, 1),
+ wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
+ );
+ winActive->Show();
+
+ return new ChildWaitLoopData(wd, winActive);
+}
+
+void wxGUIAppTraits::AlwaysYield()
+{
+ wxYield();
+}
+
+void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
+{
+ wxEndBusyCursor();
+
+ ChildWaitLoopData * const data = (ChildWaitLoopData *)dataOrig;
+
+ delete data->wd;
+
+ // finally delete the dummy frame and, as wd has been already destroyed and
+ // the other windows reenabled, the activation is going to return to the
+ // window which had had it before
+ data->winActive->Destroy();
+
+ // also delete the temporary data object itself
+ delete data;
+}
+
+bool wxGUIAppTraits::DoMessageFromThreadWait()
+{
+ // we should return false only if the app should exit, i.e. only if
+ // Dispatch() determines that the main event loop should terminate
+ wxEventLoop *evtLoop = wxEventLoop::GetActive();
+ if ( !evtLoop || !evtLoop->Pending() )
+ {
+ // no events means no quit event
+ return true;
+ }
+
+ return evtLoop->Dispatch();
+}
+
+wxPortId wxGUIAppTraits::GetToolkitVersion(int *majVer, int *minVer) const
+{
+ OSVERSIONINFO info;
+ wxZeroMemory(info);
+
+ // on Windows, the toolkit version is the same of the OS version
+ // as Windows integrates the OS kernel with the GUI toolkit.
+ info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if ( ::GetVersionEx(&info) )
+ {
+ if ( majVer )
+ *majVer = info.dwMajorVersion;
+ if ( minVer )
+ *minVer = info.dwMinorVersion;
+ }
+
+#if defined(__WXHANDHELD__) || defined(__WXWINCE__)
+ return wxPORT_WINCE;
+#else
+ return wxPORT_MSW;