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:
parent
90022ddc1e
commit
e5c0b16a78
195
src/msw/app.cpp
195
src/msw/app.cpp
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user