wxLogXXX() functions called near app termiantion shouldn't crash

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1765 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 1999-02-23 22:49:26 +00:00
parent 90022ddc1e
commit e5c0b16a78

View File

@ -9,15 +9,23 @@
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
// declarations
// ===========================================================================
// ---------------------------------------------------------------------------
// headers
// ---------------------------------------------------------------------------
#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
@ -56,11 +64,14 @@
#include "wx/resource.h"
#endif
// To UG: there's no point in putting this #if here
// if you don't do the same for the Ole calls further down.
// Also, OLE is used not just for drag and drop (it's used by automatn.cpp).
// #if wxUSE_DRAG_AND_DROP
#if !defined(__GNUWIN32__) && !defined(__SC__) && !defined(__SALFORDC__)
// OLE is used for drag-and-drop, clipboard, OLE Automation...
#if defined(__GNUWIN32__) || defined(__SC__) || defined(__SALFORDC__)
#undef wxUSE_OLE
#define wxUSE_OLE 0
#endif // broken compilers
#if wxUSE_OLE
#include <ole2.h>
#endif
@ -73,6 +84,10 @@
#include "wx/msw/msvcrt.h"
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
extern char *wxBuffer;
extern char *wxOsVersion;
extern wxList *wxWinHandleList;
@ -84,7 +99,7 @@ HINSTANCE wxhInstance = 0;
static MSG s_currentMsg;
wxApp *wxTheApp = NULL;
// @@ why not const? and not static?
// FIXME why not const? and not static?
char wxFrameClassName[] = "wxFrameClass";
char wxMDIFrameClassName[] = "wxMDIFrameClass";
char wxMDIChildFrameClassName[] = "wxMDIChildFrameClass";
@ -103,6 +118,24 @@ HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
#if defined(__WIN95__) && !defined(__TWIN32__)
#define wxUSE_RICHEDIT 1
#else
#define wxUSE_RICHEDIT 0
#endif
#if wxUSE_RICHEDIT
static HINSTANCE gs_hRichEdit = (HINSTANCE) NULL;
#endif
// ===========================================================================
// implementation
// ===========================================================================
// ---------------------------------------------------------------------------
// wxApp
// ---------------------------------------------------------------------------
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
@ -115,27 +148,16 @@ LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
long wxApp::sm_lastMessageTime = 0;
#if defined(__WIN95__) && !defined(__TWIN32__)
#define wxUSE_RICHEDIT 1
#else
#define wxUSE_RICHEDIT 0
#endif
#if wxUSE_RICHEDIT
static HINSTANCE gs_hRichEdit = (HINSTANCE) NULL;
#endif
//// Initialize
bool wxApp::Initialize()
{
// Some people may wish to use this, but
// probably it shouldn't be here by default.
#ifdef __WXDEBUG__
// wxRedirectIOToConsole();
// wxRedirectIOToConsole();
#endif
wxBuffer = new char[1500];
wxBuffer = new char[1500]; // FIXME
wxClassInfo::InitializeClasses();
@ -163,18 +185,17 @@ bool wxApp::Initialize()
if (gs_hRichEdit == (HINSTANCE) NULL)
{
wxMessageBox("Could not initialise Rich Edit DLL");
wxLogError(_("Could not initialise Rich Edit DLL"));
}
#endif
#endif // wxUSE_RICHEDIT
#endif
int iMsg = 96;
#endif // __WIN95__
// for OLE, enlarge message queue to be as large as possible
int iMsg = 96;
while (!SetMessageQueue(iMsg) && (iMsg -= 8));
/*
/*
DWORD dwOleVer;
dwOleVer = CoBuildVersion();
@ -184,17 +205,17 @@ bool wxApp::Initialize()
wxMessageBox("Incorrect version of OLE libraries.");
return FALSE;
}
*/
*/
#if !defined(__GNUWIN32__) && !defined(__SC__) && !defined(__SALFORDC__)
#if wxUSE_OLE
// we need to initialize OLE library
if ( FAILED(::OleInitialize(NULL)) )
wxFatalError(_("Cannot initialize OLE"));
wxLogError(_("Cannot initialize OLE"));
#endif
#if wxUSE_CTL3D
if (!Ctl3dRegister(wxhInstance))
wxFatalError("Cannot register CTL3D");
wxLogError("Cannot register CTL3D");
Ctl3dAutoSubclass(wxhInstance);
#endif
@ -244,8 +265,8 @@ bool wxApp::Initialize()
bool wxApp::RegisterWindowClasses()
{
///////////////////////////////////////////////////////////////////////
// Register the frame window class.
///////////////////////////////////////////////////////////////////////
// Register the frame window class.
WNDCLASS wndclass; // Structure used to register Windows class.
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
@ -256,7 +277,7 @@ bool wxApp::RegisterWindowClasses()
wndclass.hIcon = (HICON) NULL; // wxSTD_FRAME_ICON;
wndclass.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW );
wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1) ;
// wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
// wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
wndclass.lpszMenuName = NULL;
#ifdef _MULTIPLE_INSTANCES
sprintf( wxFrameClassName,"wxFrameClass%d", wxhInstance );
@ -268,8 +289,8 @@ bool wxApp::RegisterWindowClasses()
// wxFatalError("Can't register Frame Window class");
}
///////////////////////////////////////////////////////////////////////
// Register the MDI frame window class.
///////////////////////////////////////////////////////////////////////
// Register the MDI frame window class.
WNDCLASS wndclass1; // Structure used to register Windows class.
wndclass1.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
@ -279,19 +300,19 @@ bool wxApp::RegisterWindowClasses()
wndclass1.hInstance = wxhInstance;
wndclass1.hIcon = (HICON) NULL; // wxSTD_MDIPARENTFRAME_ICON;
wndclass1.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW );
// wndclass1.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1) ;
// wndclass1.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1) ;
wndclass1.hbrBackground = (HBRUSH) NULL;
wndclass1.lpszMenuName = NULL;
wndclass1.lpszClassName = wxMDIFrameClassName;
if (!RegisterClass( &wndclass1 ))
{
// wxFatalError("Can't register MDI Frame window class");
// return FALSE;
// wxFatalError("Can't register MDI Frame window class");
// return FALSE;
}
///////////////////////////////////////////////////////////////////////
// Register the MDI child frame window class.
///////////////////////////////////////////////////////////////////////
// Register the MDI child frame window class.
WNDCLASS wndclass4; // Structure used to register Windows class.
wndclass4.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
@ -305,18 +326,18 @@ bool wxApp::RegisterWindowClasses()
// paint the background itself (would OnEraseBackground duplicate
// this?)
wndclass4.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ;
// wndclass4.hbrBackground = NULL;
// wndclass4.hbrBackground = NULL;
wndclass4.lpszMenuName = NULL;
wndclass4.lpszClassName = wxMDIChildFrameClassName;
if (!RegisterClass( &wndclass4 ))
{
// wxFatalError("Can't register MDI child frame window class");
// return FALSE;
// wxFatalError("Can't register MDI child frame window class");
// return FALSE;
}
///////////////////////////////////////////////////////////////////////
// Register the panel window class.
///////////////////////////////////////////////////////////////////////
// Register the panel window class.
WNDCLASS wndclass2; // Structure used to register Windows class.
memset(&wndclass2, 0, sizeof(WNDCLASS)); // start with NULL defaults
wndclass2.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
@ -326,23 +347,23 @@ bool wxApp::RegisterWindowClasses()
wndclass2.hInstance = wxhInstance;
wndclass2.hIcon = (HICON) NULL;
wndclass2.hCursor = (HCURSOR) NULL;
// wndclass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1) ;
// wndclass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1) ;
wndclass2.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH );
wndclass2.lpszMenuName = NULL;
wndclass2.lpszClassName = wxPanelClassName;
if (!RegisterClass( &wndclass2 ))
{
// wxFatalError("Can't register Panel Window class");
// return FALSE;
// wxFatalError("Can't register Panel Window class");
// return FALSE;
}
///////////////////////////////////////////////////////////////////////
// Register the canvas and textsubwindow class name
///////////////////////////////////////////////////////////////////////
// Register the canvas and textsubwindow class name
WNDCLASS wndclass3; // Structure used to register Windows class.
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.lpfnWndProc = (WNDPROC)wxWndProc;
@ -351,14 +372,14 @@ bool wxApp::RegisterWindowClasses()
wndclass3.hInstance = wxhInstance;
wndclass3.hIcon = (HICON) NULL;
wndclass3.hCursor = (HCURSOR) NULL;
// wndclass3.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ;
// wndclass3.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ;
wndclass3.hbrBackground = (HBRUSH) NULL;
wndclass3.lpszMenuName = NULL;
wndclass3.lpszClassName = wxCanvasClassName;
if (!RegisterClass( &wndclass3))
{
// wxFatalError("Can't register Canvas class");
// return FALSE;
// wxFatalError("Can't register Canvas class");
// return FALSE;
}
return TRUE;
@ -445,10 +466,14 @@ void wxApp::CleanUp()
{
//// COMMON CLEANUP
// flush the logged messages if any
wxLog *pLog = wxLog::GetActiveTarget();
if ( pLog != NULL && pLog->HasPendingMessages() )
pLog->Flush();
// flush the logged messages if any and install a 'safer' log target: the
// default one (wxLogGui) can't be used after the resources are freed just
// below and the user suppliedo ne might be even more unsafe (using any
// wxWindows GUI function is unsafe starting from now)
wxLog::DontCreateOnDemand();
// this will flush the old messages if any
delete wxLog::SetActiveTarget(new wxLogStderr);
// One last chance for pending objects to be cleaned up
wxTheApp->DeletePendingObjects();
@ -458,13 +483,12 @@ void wxApp::CleanUp()
#if wxUSE_WX_RESOURCES
wxCleanUpResourceSystem();
// wxDefaultResourceTable->ClearTable();
// 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).
// 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;
@ -515,7 +539,7 @@ void wxApp::CleanUp()
if ( wxDisableButtonBrush )
::DeleteObject( wxDisableButtonBrush ) ;
#if !defined(__GNUWIN32__) && !defined(__SC__) && !defined(__SALFORDC__)
#if wxUSE_OLE
::OleUninitialize();
#endif
@ -542,17 +566,17 @@ void wxApp::CleanUp()
wxDebugContext::Dump();
wxDebugContext::PrintStatistics();
}
// wxDebugContext::SetStream(NULL, NULL);
// wxDebugContext::SetStream(NULL, NULL);
#endif
// do it as the very last thing because everything else can log messages
wxLog::DontCreateOnDemand();
delete wxLog::SetActiveTarget(NULL);
}
#if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
// temporarily disable this warning
// temporarily disable this warning which would be generated in release builds
// because of __try
#ifdef __VISUALC__
#pragma warning(disable: 4715) // not all control paths return a value
#endif // Visual C++
@ -653,6 +677,13 @@ int wxEntry(WXHINSTANCE hInstance,
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()
// NOTREACHED
@ -677,22 +708,15 @@ int wxEntry(WXHINSTANCE hInstance)
// 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;
}
wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
"No initializer - use IMPLEMENT_APP macro." );
wxTheApp = (* wxApp::GetInitializerFunction()) ();
}
if (!wxTheApp) {
MessageBox(NULL, "You have to define an instance of wxApp!", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
return 0;
}
wxCHECK_MSG( wxTheApp, 0, "You have to define an instance of wxApp!" );
wxTheApp->argc = 0;
wxTheApp->argv = NULL;
@ -701,8 +725,10 @@ int wxEntry(WXHINSTANCE hInstance)
wxTheApp->OnInit();
if (wxTheApp->GetTopWindow() && wxTheApp->GetTopWindow()->GetHWND()) {
wxTheApp->GetTopWindow()->Show(TRUE);
wxWindow *topWindow = wxTheApp->GetTopWindow();
if ( topWindow && topWindow->GetHWND())
{
topWindow->Show(TRUE);
}
return 1;
@ -861,9 +887,9 @@ int wxApp::MainLoop()
while ( m_keepGoing )
{
#if wxUSE_THREADS
#if wxUSE_THREADS
wxMutexGuiLeaveOrEnter();
#endif // wxUSE_THREADS
#endif // wxUSE_THREADS
while ( !::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) &&
ProcessIdle() )
@ -1102,8 +1128,9 @@ int wxApp::GetComCtl32Version() const
void wxExit()
{
wxLogError(_("Fatal error: exiting"));
wxApp::CleanUp();
FatalAppExit(0, "Fatal error: exiting");
}
// Yield to incoming messages
@ -1134,5 +1161,5 @@ void wxSetInstance(HINSTANCE hInst)
// 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(__VISUALC__) && !defined(__WIN32__)) || (defined(__GNUWIN32__) && !defined(__TWIN32__))
#include "main.cpp"
#include "main.cpp"
#endif