X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dfad0599246651d4994e348d868a3e65613c7379..6f63ec3f93070e6824da775cf8d2565a025c2406:/src/msw/app.cpp diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 2af264ff65..300ec55493 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -10,14 +10,14 @@ ///////////////////////////////////////////////////////////////////////////// #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 @@ -50,17 +50,32 @@ #include #endif -// use debug CRT functions for memory leak detections in VC++ -/* This still doesn't work for me, Vadim. -#if defined(__WXDEBUG__) && defined(_MSC_VER) +// use debug CRT functions for memory leak detections in VC++ if we're not +// using wxWindows own methods +#if defined(__WXDEBUG__) && defined(_MSC_VER) && !wxUSE_GLOBAL_MEMORY_OPERATORS && !defined(__NO_VC_CRTDBG__) + #define wxUSE_VC_CRTDBG +#else + #undef wxUSE_VC_CRTDBG +#endif + +#ifdef wxUSE_VC_CRTDBG // VC++ uses this macro as debug/release mode indicator #ifndef _DEBUG #define _DEBUG #endif + /* Need to undef new if including crtdbg.h */ + #ifdef new + #undef new + #endif + #include + + #if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS + #define new new(__FILE__,__LINE__) + #endif + #endif -*/ extern char *wxBuffer; extern char *wxOsVersion; @@ -97,6 +112,8 @@ LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM); BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) EVT_IDLE(wxApp::OnIdle) + EVT_END_SESSION(wxApp::OnEndSession) + EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession) END_EVENT_TABLE() #endif @@ -110,47 +127,40 @@ long wxApp::sm_lastMessageTime = 0; bool wxApp::Initialize() { - wxBuffer = new char[1500]; + // Some people may wish to use this, but + // probably it shouldn't be here by default. +#ifdef __WXDEBUG__ +// wxRedirectIOToConsole(); +#endif -/* - #if defined(__WXDEBUG__) && defined(_MSC_VER) + wxBuffer = new char[1500]; + +#ifdef wxUSE_VC_CRTDBG // do check for memory leaks on program exit // (another useful flag is _CRTDBG_DELAY_FREE_MEM_DF which doesn't free // deallocated memory which may be used to simulate low-memory condition) _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); - #endif // debug build under MS VC++ -*/ +#endif // debug build under MS VC++ - #if (WXDEBUG && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - #if defined(_WINDLL) - streambuf* sBuf = NULL; - #else // EXE - streambuf* sBuf = new wxDebugStreamBuf; - #endif // DLL + wxClassInfo::InitializeClasses(); - ostream* oStr = new ostream(sBuf) ; - wxDebugContext::SetStream(oStr, sBuf); - #endif // wxUSE_MEMORY_TRACING - - wxClassInfo::InitializeClasses(); - - #if wxUSE_RESOURCES +#if wxUSE_RESOURCES wxGetResource("wxWindows", "OsVersion", &wxOsVersion); - #endif +#endif - wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); - wxTheColourDatabase->Initialize(); + wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); + wxTheColourDatabase->Initialize(); - wxInitializeStockLists(); - wxInitializeStockObjects(); + wxInitializeStockLists(); + wxInitializeStockObjects(); - #if wxUSE_WX_RESOURCES +#if wxUSE_WX_RESOURCES wxInitializeResourceSystem(); - #endif +#endif - wxBitmap::InitStandardHandlers(); + wxBitmap::InitStandardHandlers(); - #if defined(__WIN95__) +#if defined(__WIN95__) InitCommonControls(); gs_hRichEdit = LoadLibrary("RICHED32.DLL"); @@ -158,60 +168,77 @@ bool wxApp::Initialize() { wxMessageBox("Could not initialise Rich Edit DLL"); } - #endif +#endif + + int iMsg = 96; + + // for OLE, enlarge message queue to be as large as possible + while (!SetMessageQueue(iMsg) && (iMsg -= 8)); - #if defined(WX_DRAG_DROP) +/* + DWORD dwOleVer; + dwOleVer = CoBuildVersion(); + + // check the OLE library version + if (rmm != HIWORD(dwOleVer)) + { + wxMessageBox("Incorrect version of OLE libraries."); + return FALSE; + } +*/ + +#ifndef __GNUWIN32__ // we need to initialize OLE library if ( FAILED(::OleInitialize(NULL)) ) wxFatalError(_("Cannot initialize OLE")); - #endif +#endif - #if CTL3D +#if CTL3D if (!Ctl3dRegister(wxhInstance)) wxFatalError("Cannot register CTL3D"); Ctl3dAutoSubclass(wxhInstance); - #endif +#endif - g_globalCursor = new wxCursor; + g_globalCursor = new wxCursor; - wxSTD_FRAME_ICON = LoadIcon(wxhInstance, "wxSTD_FRAME"); - wxSTD_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDIPARENTFRAME"); - wxSTD_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDICHILDFRAME"); + wxSTD_FRAME_ICON = LoadIcon(wxhInstance, "wxSTD_FRAME"); + wxSTD_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDIPARENTFRAME"); + wxSTD_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxSTD_MDICHILDFRAME"); - wxDEFAULT_FRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_FRAME"); - wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDIPARENTFRAME"); - wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDICHILDFRAME"); + wxDEFAULT_FRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_FRAME"); + wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDIPARENTFRAME"); + wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, "wxDEFAULT_MDICHILDFRAME"); - RegisterWindowClasses(); + RegisterWindowClasses(); - // Create the brush for disabling bitmap buttons + // Create the brush for disabling bitmap buttons - LOGBRUSH lb ; - lb.lbStyle = BS_PATTERN; - lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ) ; - wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ; - ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ; + LOGBRUSH lb ; + lb.lbStyle = BS_PATTERN; + lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ) ; + wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ; + ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ; - #if wxUSE_PENWINDOWS +#if wxUSE_PENWINDOWS wxRegisterPenWin(); - #endif +#endif - wxWinHandleList = new wxList(wxKEY_INTEGER); + wxWinHandleList = new wxList(wxKEY_INTEGER); - // This is to foil optimizations in Visual C++ that - // throw out dummy.obj. - #if (_MSC_VER >= 800) && !defined(WXMAKINGDLL) + // This is to foil optimizations in Visual C++ that + // throw out dummy.obj. +#if (_MSC_VER >= 800) && !defined(WXMAKINGDLL) extern char wxDummyChar; if (wxDummyChar) wxDummyChar++; - #endif +#endif - wxSetKeyboardHook(TRUE); + wxSetKeyboardHook(TRUE); - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) - return FALSE; - return TRUE; + wxModule::RegisterModules(); + if (!wxModule::InitializeModules()) + return FALSE; + return TRUE; } //// RegisterWindowClasses @@ -342,83 +369,76 @@ bool wxApp::RegisterWindowClasses() //// Convert Windows to argc, argv style -// FIXME this code should be rewritten (use wxArrayString instead...) void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine) { - // Split command line into tokens, as in usual main(argc, argv) - char **command = new char*[50]; // VZ: sure? why not 25 or 73 and a half?? - - int count = 0; - char *buf = new char[strlen(lpCmdLine) + 1]; + wxStringList args; - /* Model independent strcpy */ - int i; - for (i = 0; (buf[i] = lpCmdLine[i]) != 0; i++) - { - /* loop */; - } + wxString cmdLine(lpCmdLine); + int count = 0; - // Get application name - char name[260]; // 260 is MAX_PATH value from windef.h - ::GetModuleFileName(wxhInstance, name, WXSIZEOF(name)); + // Get application name + char name[260]; // 260 is MAX_PATH value from windef.h + ::GetModuleFileName(wxhInstance, name, WXSIZEOF(name)); - // Is it only 16-bit Borland that already copies the program name - // to the first argv index? + // GNUWIN32 already fills in the first arg with the application name. #if !defined(__GNUWIN32__) -// #if ! (defined(__BORLANDC__) && !defined(__WIN32__)) - command[count++] = copystring(name); -// #endif + args.Add(name); + count ++; #endif - strcpy(name, wxFileNameFromPath(name)); - wxStripExtension(name); - wxTheApp->SetAppName(name); + strcpy(name, wxFileNameFromPath(name)); + wxStripExtension(name); + wxTheApp->SetAppName(name); - /* Break up string */ - // Treat strings enclosed in double-quotes as single arguments - char* str = buf; - while (*str) - { -/* - if ( count == WXSIZEOF(command) ) + // Break up string + // Treat strings enclosed in double-quotes as single arguments + int i = 0; + int len = cmdLine.Length(); + while (i < len) { - wxFAIL_MSG("too many command line args."); - break; - } -*/ - while ( *str && isspace(*str) ) // skip whitespace - str++; + // Skip whitespace + while ((i < len) && isspace(cmdLine.GetChar(i))) + i ++; - if (*str == '"') - { - str++; - command[count++] = str; - while (*str && *str != '"') - str++; + if (i < len) + { + if (cmdLine.GetChar(i) == '"') // We found the start of a string + { + i ++; + int first = i; + while ((i < len) && (cmdLine.GetChar(i) != '"')) + i ++; + + wxString arg(cmdLine.Mid(first, (i - first))); + + args.Add(arg); + count ++; + + if (i < len) + i ++; // Skip past 2nd quote + } + else // Unquoted argument + { + int first = i; + while ((i < len) && !isspace(cmdLine.GetChar(i))) + i ++; + + wxString arg(cmdLine.Mid(first, (i - first))); + + args.Add(arg); + count ++; + } + } } - else if (*str) + + wxTheApp->argv = new char*[count + 1]; + for (i = 0; i < count; i++) { - command[count++] = str; - while (*str && !isspace(*str)) - str++; + wxString arg(args[i]); + wxTheApp->argv[i] = copystring((const char*)arg); } - if (*str) - *str++ = '\0'; - } - - wxTheApp->argv = new char*[count + 1]; - wxTheApp->argv[count] = NULL; /* argv[] is NULL terminated list! */ - wxTheApp->argc = count; - - for (i = 0; i < count; i++) - { - wxTheApp->argv[i] = copystring(command[i]); - - delete [] command[i]; - } - - delete [] command; - delete [] buf; + wxTheApp->argv[count] = NULL; // argv[] is a NULL-terminated list + wxTheApp->argc = count; } //// Cleans up any wxWindows internal structures left lying around @@ -484,7 +504,7 @@ void wxApp::CleanUp() if ( wxDisableButtonBrush ) ::DeleteObject( wxDisableButtonBrush ) ; -#if defined(WX_DRAG_DROP) +#ifndef __GNUWIN32__ ::OleUninitialize(); #endif @@ -497,6 +517,23 @@ void wxApp::CleanUp() wxClassInfo::CleanUpClasses(); + delete wxTheApp; + wxTheApp = NULL; + +#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT + // At this point we want to check if there are any memory + // blocks that aren't part of the wxDebugContext itself, + // as a special case. Then when dumping we need to ignore + // wxDebugContext, too. + if (wxDebugContext::CountObjectsLeft() > 0) + { + wxLogDebug("There were memory leaks."); + wxDebugContext::Dump(); + wxDebugContext::PrintStatistics(); + } +// wxDebugContext::SetStream(NULL, NULL); +#endif + // do it as the very last thing because everything else can log messages wxLog::DontCreateOnDemand(); delete wxLog::SetActiveTarget(NULL); @@ -571,24 +608,14 @@ int wxEntry(WXHINSTANCE hInstance, } wxTheApp->OnExit(); - wxApp::CleanUp(); - delete wxTheApp; - wxTheApp = NULL; + // flush the logged messages if any + wxLog *pLog = wxLog::GetActiveTarget(); + if ( pLog != NULL && pLog->HasPendingMessages() ) + pLog->Flush(); -#if (WXDEBUG && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - // At this point we want to check if there are any memory - // blocks that aren't part of the wxDebugContext itself, - // as a special case. Then when dumping we need to ignore - // wxDebugContext, too. - if (wxDebugContext::CountObjectsLeft() > 0) - { - wxTrace("There were memory leaks.\n"); - wxDebugContext::Dump(); - wxDebugContext::PrintStatistics(); - } - wxDebugContext::SetStream(NULL, NULL); -#endif + + wxApp::CleanUp(); return retValue; #ifndef __WXDEBUG__ // catch exceptions only in release build @@ -678,7 +705,7 @@ wxApp::~wxApp() { delete[] argv[i]; } - delete argv; + delete[] argv; } bool wxApp::Initialized() @@ -857,12 +884,12 @@ bool wxApp::SendIdleEvents(wxWindow* win) wxIdleEvent event; event.SetEventObject(win); - win->ProcessEvent(event); + win->GetEventHandler()->ProcessEvent(event); if (event.MoreRequested()) needMore = TRUE; - wxNode* node = win->GetChildren()->First(); + wxNode* node = win->GetChildren().First(); while (node) { wxWindow* win = (wxWindow*) node->Data(); @@ -892,6 +919,23 @@ void wxApp::DeletePendingObjects() } } +void wxApp::OnEndSession(wxCloseEvent& event) +{ + if (GetTopWindow()) + GetTopWindow()->Close(TRUE); +} + +// Default behaviour: close the application with prompts. The +// user can veto the close, and therefore the end session. +void wxApp::OnQueryEndSession(wxCloseEvent& event) +{ + if (GetTopWindow()) + { + if (!GetTopWindow()->Close(!event.CanVeto())) + event.Veto(TRUE); + } +} + wxLog* wxApp::CreateLogTarget() { return new wxLogGui;