#include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS
-// OLE is used for drag-and-drop, clipboard, OLE Automation...
-#ifndef wxUSE_NORLANDER_HEADERS
-#if defined(__GNUWIN32__) || defined(__SC__) || defined(__SALFORDC__)
+// OLE is used for drag-and-drop, clipboard, OLE Automation..., but some
+// compilers don't support it (missing headers, libs, ...)
+#if defined(__GNUWIN32_OLD__) || defined(__SC__) || defined(__SALFORDC__)
#undef wxUSE_OLE
#define wxUSE_OLE 0
#endif // broken compilers
-#endif
#if wxUSE_OLE
#include <ole2.h>
#include <string.h>
#include <ctype.h>
-#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
+#if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) || defined(__TWIN32__))
#include <commctrl.h>
#endif
extern wxList *wxWinHandleList;
extern wxList WXDLLEXPORT wxPendingDelete;
extern void wxSetKeyboardHook(bool doIt);
-extern wxCursor *g_globalCursor;
MSG s_currentMsg;
wxApp *wxTheApp = NULL;
const wxChar *wxMDIChildFrameClassName = wxT("wxMDIChildFrameClass");
const wxChar *wxMDIChildFrameClassNameNoRedraw = wxT("wxMDIChildFrameClassNR");
const wxChar *wxPanelClassName = wxT("wxPanelClass");
+const wxChar *wxPanelClassNameNR = wxT("wxPanelClassNR");
const wxChar *wxCanvasClassName = wxT("wxCanvasClass");
+const wxChar *wxCanvasClassNameNR = wxT("wxCanvasClassNR");
HICON wxSTD_FRAME_ICON = (HICON) NULL;
HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL;
LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
+#if wxUSE_ON_FATAL_EXCEPTION
+ static bool gs_handleExceptions = FALSE;
+#endif
+
// ===========================================================================
// implementation
// ===========================================================================
Ctl3dAutoSubclass(wxhInstance);
#endif
- g_globalCursor = new wxCursor;
-
// VZ: these icons are not in wx.rc anyhow (but should they?)!
#if 0
wxSTD_FRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_FRAME"));
return FALSE;
}
+ // Register the no redraw panel window class.
+ wndclass.lpszClassName = wxPanelClassNameNR;
+ wndclass.style = styleNoRedraw;
+
+ if ( !RegisterClass(&wndclass) )
+ {
+ wxLogLastError("RegisterClass(no redraw panel)");
+
+ return FALSE;
+ }
+
// Register the canvas and textsubwindow class name
wndclass.hbrBackground = (HBRUSH)NULL;
wndclass.lpszClassName = wxCanvasClassName;
return FALSE;
}
+ wndclass.lpszClassName = wxCanvasClassNameNR;
+ wndclass.style = styleNoRedraw;
+ if ( !RegisterClass(&wndclass) )
+ {
+ wxLogLastError("RegisterClass(no redraw canvas)");
+
+ return FALSE;
+ }
+
return TRUE;
}
// 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;
- g_globalCursor = NULL;
-
wxDeleteStockObjects();
// Destroy all GDI lists, etc.
// wxDebugContext, too.
if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
{
- wxLogDebug(wxT("There were memory leaks."));
+ wxLogMessage(wxT("There were memory leaks."));
wxDebugContext::Dump();
wxDebugContext::PrintStatistics();
}
#endif // wxUSE_LOG
}
+//----------------------------------------------------------------------
+// Entry point helpers, used by wxPython
+//----------------------------------------------------------------------
+
+int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char** WXUNUSED(argv) )
+{
+ return wxApp::Initialize();
+}
+
+int WXDLLEXPORT wxEntryInitGui()
+{
+ wxTheApp->OnInitGui();
+ return 0;
+}
+
+void WXDLLEXPORT wxEntryCleanup()
+{
+ wxApp::CleanUp();
+}
+
+
#if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
// temporarily disable this warning which would be generated in release builds
#pragma warning(disable: 4715) // not all control paths return a value
#endif // Visual C++
-//// Main wxWindows entry point
+//----------------------------------------------------------------------
+// Main wxWindows entry point
+//----------------------------------------------------------------------
int wxEntry(WXHINSTANCE hInstance,
WXHINSTANCE WXUNUSED(hPrevInstance),
char *lpCmdLine,
wxDebugContext::SetCheckpoint();
#endif
#endif
- // take everything into a try-except block in release build
+
+ // 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!
-#if !defined(__WXDEBUG__) && defined(__VISUALC__)
- #define CATCH_PROGRAM_EXCEPTIONS
+#ifndef __VISUALC__
+ #undef wxUSE_ON_FATAL_EXCEPTION
+ #define wxUSE_ON_FATAL_EXCEPTION 0
+#endif // VC++
+#if wxUSE_ON_FATAL_EXCEPTION
__try {
-#else
- #undef CATCH_PROGRAM_EXCEPTIONS
#endif
wxhInstance = (HINSTANCE) hInstance;
- if (!wxApp::Initialize())
+ if (!wxEntryStart(0,0))
return 0;
// create the application object or ensure that one already exists
// GUI-specific initialisation. In fact on Windows we don't have any,
// but this call is provided for compatibility across platforms.
- wxTheApp->OnInitGui();
+ wxEntryInitGui();
// We really don't want timestamps by default, because it means
// we can't simply double-click on the error message and get to that
wxTheApp->OnExit();
- wxApp::CleanUp();
+ wxEntryCleanup();
return retValue;
-#ifdef CATCH_PROGRAM_EXCEPTIONS
+#if wxUSE_ON_FATAL_EXCEPTION
}
- __except ( EXCEPTION_EXECUTE_HANDLER ) {
- /*
- if ( wxTheApp )
+ __except ( gs_handleExceptions ? EXCEPTION_EXECUTE_HANDLER
+ : EXCEPTION_CONTINUE_SEARCH ) {
+ if ( wxTheApp )
wxTheApp->OnFatalException();
- */
// using wxLog would be unsafe here
::MessageBox(NULL,
// NOTREACHED
}
-#endif // CATCH_PROGRAM_EXCEPTIONS
+#endif // wxUSE_ON_FATAL_EXCEPTION
}
// restore warning state
#else /* _WINDLL */
-//// Entry point for DLLs
+//----------------------------------------------------------------------
+// Entry point for wxWindows + the App in a DLL
+//----------------------------------------------------------------------
int wxEntry(WXHINSTANCE hInstance)
{
wxhInstance = (HINSTANCE) hInstance;
- wxApp::Initialize();
+ wxEntryStart(0, 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
wxTheApp->argc = 0;
wxTheApp->argv = NULL;
- wxTheApp->OnInitGui();
+ wxEntryInitGui();
wxTheApp->OnInit();
return TRUE;
else
return FALSE;
-#endif
-#ifdef _WINDLL // Assume initialized if DLL (no way of telling)
+#else // Assume initialized if DLL (no way of telling)
return TRUE;
#endif
}
s_inOnIdle = TRUE;
+ // If there are pending events, we must process them: pending events
+ // are either events to the threads other than main or events posted
+ // with wxPostEvent() functions
+ // GRG: I have moved this here so that all pending events are processed
+ // before starting to delete any objects. This behaves better (in
+ // particular, wrt wxPostEvent) and is coherent with wxGTK's current
+ // behaviour. Changed Feb/2000 before 2.1.14
+ ProcessPendingEvents();
+
// 'Garbage' collection of windows deleted with Close().
DeletePendingObjects();
#if wxUSE_LOG
// flush the logged messages if any
- wxLog *pLog = wxLog::GetActiveTarget();
- if ( pLog != NULL && pLog->HasPendingMessages() )
- pLog->Flush();
+ wxLog::FlushActive();
#endif // wxUSE_LOG
// Send OnIdle events to all windows
event.RequestMore(TRUE);
}
- // If they are pending events, we must process them: pending events are
- // either events to the threads other than main or events posted with
- // wxPostEvent() functions
- ProcessPendingEvents();
-
s_inOnIdle = FALSE;
}
wxLogError(_("Fatal error: exiting"));
wxApp::CleanUp();
+ exit(0);
}
// Yield to incoming messages
bool wxYield()
{
+ // disable log flushing from here because a call to wxYield() shouldn't
+ // normally result in message boxes popping up &c
+ wxLog::Suspend();
+
// 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;
while ( PeekMessage(&msg, (HWND)0, 0, 0, PM_NOREMOVE) &&
msg.message != WM_QUIT )
{
+#if wxUSE_THREADS
+ wxMutexGuiLeaveOrEnter();
+#endif // wxUSE_THREADS
+
if ( !wxTheApp->DoMessage() )
break;
}
// If they are pending events, we must process them.
- wxTheApp->ProcessPendingEvents();
+ if (wxTheApp)
+ wxTheApp->ProcessPendingEvents();
+
+ // let the logs be flashed again
+ wxLog::Resume();
+
+ return TRUE;
+}
+
+bool wxHandleFatalExceptions(bool doit)
+{
+#if wxUSE_ON_FATAL_EXCEPTION
+ // assume this can only be called from the main thread
+ gs_handleExceptions = doit;
return TRUE;
+#else
+ wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to sue this function"));
+
+ return FALSE;
+#endif
}
//-----------------------------------------------------------------------------