X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2bdf7154639d1ef019ef63f9e4bfed753d9cf012..55826fcf4fd863d48ac28789d99bbb5c8a8d4c7e:/src/msw/app.cpp diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 0cee8d9455..dd14f9b063 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -48,7 +48,7 @@ #include "wx/log.h" #endif -#include "wx/cmdline.h" +#include "wx/apptrait.h" #include "wx/filename.h" #include "wx/module.h" @@ -84,14 +84,10 @@ #include #include -#if defined(__WIN95__) && !((defined(__GNUWIN32_OLD__) || defined(__TWIN32__) || defined(__WXMICROWIN__)) && !defined(__CYGWIN10__)) +#if defined(__WIN95__) && !((defined(__GNUWIN32_OLD__) || defined(__WXMICROWIN__)) && !defined(__CYGWIN10__)) #include #endif -#ifndef __WXMICROWIN__ -#include "wx/msw/msvcrt.h" -#endif - // ---------------------------------------------------------------------------- // conditional compilation // ---------------------------------------------------------------------------- @@ -123,14 +119,12 @@ // global variables // --------------------------------------------------------------------------- -extern wxChar *wxBuffer; extern wxList WXDLLEXPORT wxPendingDelete; #ifndef __WXMICROWIN__ extern void wxSetKeyboardHook(bool doIt); #endif MSG s_currentMsg; -wxApp *wxTheApp = NULL; // NB: all "NoRedraw" classes must have the same names as the "normal" classes // with NR suffix - wxWindow::MSWCreate() supposes this @@ -141,42 +135,103 @@ const wxChar *wxMDIFrameClassNameNoRedraw = wxT("wxMDIFrameClassNR"); const wxChar *wxMDIChildFrameClassName = wxT("wxMDIChildFrameClass"); const wxChar *wxMDIChildFrameClassNameNoRedraw = wxT("wxMDIChildFrameClassNR"); -HICON wxSTD_FRAME_ICON = (HICON) NULL; -HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL; -HICON wxSTD_MDIPARENTFRAME_ICON = (HICON) NULL; - -HICON wxDEFAULT_FRAME_ICON = (HICON) NULL; -HICON wxDEFAULT_MDICHILDFRAME_ICON = (HICON) NULL; -HICON wxDEFAULT_MDIPARENTFRAME_ICON = (HICON) NULL; - HBRUSH wxDisableButtonBrush = (HBRUSH) 0; -#ifdef __DIGITALMARS__ -extern "C" LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM); -#else +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM); -#endif -// 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; -#endif +// =========================================================================== +// 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(), + -1, + _T(""), + 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(); + + const 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(); +} + +bool wxGUIAppTraits::DoMessageFromThreadWait() +{ + return !wxTheApp || wxTheApp->DoMessage(); +} // =========================================================================== -// implementation +// wxApp implementation // =========================================================================== +int wxApp::m_nCmdShow = SW_SHOWNORMAL; + // --------------------------------------------------------------------------- -// wxApp +// wxWin macros // --------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) @@ -187,9 +242,29 @@ BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession) END_EVENT_TABLE() +// class to ensure that wxAppBase::CleanUp() is called if our Initialize() +// fails +class wxCallBaseCleanup +{ +public: + wxCallBaseCleanup(wxApp *app) : m_app(app) { } + ~wxCallBaseCleanup() { if ( m_app ) m_app->wxAppBase::CleanUp(); } + + void Dismiss() { m_app = NULL; } + +private: + wxApp *m_app; +}; + //// Initialize -bool wxApp::Initialize() +bool wxApp::Initialize(int& argc, wxChar **argv) { + if ( !wxAppBase::Initialize(argc, argv) ) + return false; + + // ensure that base cleanup is done if we return too early + wxCallBaseCleanup callBaseCleanup(this); + // the first thing to do is to check if we're trying to run an Unicode // program under Win9x w/o MSLU emulation layer - if so, abort right now // as it has no chance to work @@ -211,22 +286,6 @@ bool wxApp::Initialize() } #endif // wxUSE_UNICODE && !wxUSE_UNICODE_MSLU - wxBuffer = new wxChar[1500]; // FIXME - - wxClassInfo::InitializeClasses(); - -#if wxUSE_THREADS - wxPendingEventsLocker = new wxCriticalSection; -#endif - - wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); - wxTheColourDatabase->Initialize(); - - wxInitializeStockLists(); - wxInitializeStockObjects(); - - wxBitmap::InitStandardHandlers(); - #if defined(__WIN95__) && !defined(__WXMICROWIN__) InitCommonControls(); #endif // __WIN95__ @@ -255,17 +314,6 @@ bool wxApp::Initialize() Ctl3dAutoSubclass(wxhInstance); #endif // wxUSE_CTL3D - // VZ: these icons are not in wx.rc anyhow (but should they?)! -#if 0 - wxSTD_FRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_FRAME")); - wxSTD_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_MDIPARENTFRAME")); - wxSTD_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_MDICHILDFRAME")); - - wxDEFAULT_FRAME_ICON = LoadIcon(wxhInstance, wxT("wxDEFAULT_FRAME")); - wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(wxhInstance, wxT("wxDEFAULT_MDIPARENTFRAME")); - wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(wxhInstance, wxT("wxDEFAULT_MDICHILDFRAME")); -#endif // 0 - RegisterWindowClasses(); #ifndef __WXMICROWIN__ @@ -300,10 +348,9 @@ bool wxApp::Initialize() wxSetKeyboardHook(TRUE); #endif - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) - return FALSE; - return TRUE; + callBaseCleanup.Dismiss(); + + return true; } // --------------------------------------------------------------------------- @@ -448,80 +495,8 @@ bool wxApp::UnregisterWindowClasses() return retval; } -// --------------------------------------------------------------------------- -// Convert Windows to argc, argv style -// --------------------------------------------------------------------------- - -void wxApp::ConvertToStandardCommandArgs(const char* lpCmdLine) -{ - // break the command line in words - wxArrayString args = - wxCmdLineParser::ConvertStringToArgs(wxConvertMB2WX(lpCmdLine)); - - // +1 here for the program name - argc = args.GetCount() + 1; - - // and +1 here for the terminating NULL - argv = new wxChar *[argc + 1]; - - argv[0] = new wxChar[260]; // 260 is MAX_PATH value from windef.h - ::GetModuleFileName(wxhInstance, argv[0], 260); - - // also set the app name from argv[0] - wxString name; - wxFileName::SplitPath(argv[0], NULL, &name, NULL); - - // but don't override the name already set by the user code, if any - if ( GetAppName().empty() ) - SetAppName(name); - - // copy all the other arguments to wxApp::argv[] - for ( int i = 1; i < argc; i++ ) - { - argv[i] = copystring(args[i - 1]); - } - - // argv[] must be NULL-terminated - argv[argc] = NULL; -} - -//// Cleans up any wxWindows internal structures left lying around - void wxApp::CleanUp() { - //// COMMON CLEANUP - -#if wxUSE_LOG - // 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); -#endif // wxUSE_LOG - - // One last chance for pending objects to be cleaned up - wxTheApp->DeletePendingObjects(); - - wxModule::CleanUpModules(); - - wxDeleteStockObjects(); - - // Destroy all GDI lists, etc. - wxDeleteStockLists(); - - delete wxTheColourDatabase; - wxTheColourDatabase = NULL; - - wxBitmap::CleanUpHandlers(); - - delete[] wxBuffer; - wxBuffer = NULL; - - //// WINDOWS-SPECIFIC CLEANUP - #ifndef __WXMICROWIN__ wxSetKeyboardHook(FALSE); #endif @@ -530,20 +505,6 @@ void wxApp::CleanUp() wxCleanUpPenWin(); #endif - if (wxSTD_FRAME_ICON) - DestroyIcon(wxSTD_FRAME_ICON); - if (wxSTD_MDICHILDFRAME_ICON) - DestroyIcon(wxSTD_MDICHILDFRAME_ICON); - if (wxSTD_MDIPARENTFRAME_ICON) - DestroyIcon(wxSTD_MDIPARENTFRAME_ICON); - - if (wxDEFAULT_FRAME_ICON) - DestroyIcon(wxDEFAULT_FRAME_ICON); - if (wxDEFAULT_MDICHILDFRAME_ICON) - DestroyIcon(wxDEFAULT_MDICHILDFRAME_ICON); - if (wxDEFAULT_MDIPARENTFRAME_ICON) - DestroyIcon(wxDEFAULT_MDIPARENTFRAME_ICON); - if ( wxDisableButtonBrush ) ::DeleteObject( wxDisableButtonBrush ); @@ -551,277 +512,44 @@ void wxApp::CleanUp() ::OleUninitialize(); #endif -#ifdef WXMAKINGDLL // for an EXE the classes are unregistered when it terminates but DLL may // be loaded several times (load/unload/load) into the same process in // which case the registration will fail after the first time if we don't // unregister the classes now UnregisterWindowClasses(); -#endif // WXMAKINGDLL #if wxUSE_CTL3D Ctl3dUnregister(wxhInstance); #endif delete wxWinHandleHash; - wxWinHandleHash = NULL; // Set to null in case anything later tries to ref it. - - delete wxPendingEvents; - wxPendingEvents = NULL; // Set to null because wxAppBase::wxEvtHandler is destroyed later. - -#if wxUSE_THREADS - delete wxPendingEventsLocker; - wxPendingEventsLocker = NULL; // Set to null because wxAppBase::wxEvtHandler is destroyed later. - // If we don't do the following, we get an apparent memory leak -#if wxUSE_VALIDATORS - ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker(); -#endif // wxUSE_VALIDATORS -#endif // wxUSE_THREADS - - 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(TRUE) > 0) - { - wxLogMessage(wxT("There were memory leaks.")); - wxDebugContext::Dump(); - wxDebugContext::PrintStatistics(); - } - // wxDebugContext::SetStream(NULL, NULL); -#endif - -#if wxUSE_LOG - // do it as the very last thing because everything else can log messages - delete wxLog::SetActiveTarget(NULL); -#endif // wxUSE_LOG -} - -//---------------------------------------------------------------------- -// Entry point helpers, used by wxPython -//---------------------------------------------------------------------- - -int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char** WXUNUSED(argv) ) -{ - return wxApp::Initialize(); -} - -int WXDLLEXPORT wxEntryInitGui() -{ - return wxTheApp->OnInitGui(); -} - -void WXDLLEXPORT wxEntryCleanup() -{ - wxApp::CleanUp(); -} - - -#if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL)) - -// 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++ - -//---------------------------------------------------------------------- -// Main wxWindows entry point -//---------------------------------------------------------------------- -int wxEntry(WXHINSTANCE hInstance, - WXHINSTANCE WXUNUSED(hPrevInstance), - char *lpCmdLine, - int nCmdShow, - bool enterLoop) -{ - // 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) -#ifndef __WXMICROWIN__ - wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); -#endif - -#ifdef __MWERKS__ -#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - // This seems to be necessary since there are 'rogue' - // objects present at this point (perhaps global objects?) - // Setting a checkpoint will ignore them as far as the - // memory checking facility is concerned. - // Of course you may argue that memory allocated in globals should be - // checked, but this is a reasonable compromise. - wxDebugContext::SetCheckpoint(); -#endif -#endif - - // take everything into a try-except block to be able to call - // OnFatalException() if necessary -#if wxUSE_ON_FATAL_EXCEPTION - __try { -#endif - wxhInstance = (HINSTANCE) hInstance; + wxWinHandleHash = NULL; - if (!wxEntryStart(0,0)) - return 0; - - // create the application object or ensure that one already exists - if (!wxTheApp) - { - // 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. - wxCHECK_MSG( wxApp::GetInitializerFunction(), 0, - wxT("No initializer - use IMPLEMENT_APP macro.") ); - - wxTheApp = (wxApp*) (*wxApp::GetInitializerFunction()) (); - } - - wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") ); - - // save the WinMain() parameters - if (lpCmdLine) // MicroWindows passes NULL - wxTheApp->ConvertToStandardCommandArgs(lpCmdLine); - wxTheApp->m_nCmdShow = nCmdShow; - - // 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 - // line in the source. So VC++ at least, let's have a sensible default. -#ifdef __VISUALC__ -#if wxUSE_LOG - wxLog::SetTimestamp(NULL); -#endif // wxUSE_LOG -#endif // __VISUALC__ - - // init the app - int retValue = wxEntryInitGui() && wxTheApp->OnInit() ? 0 : -1; - - if ( retValue == 0 ) - { - if ( enterLoop ) - { - // run the main loop - wxTheApp->OnRun(); - } - else - { - // we want to initialize, but not run or exit immediately. - return 1; - } - } - //else: app initialization failed, so we skipped OnRun() - - wxWindow *topWindow = wxTheApp->GetTopWindow(); - if ( topWindow ) - { - // Forcibly delete the window. - if ( topWindow->IsKindOf(CLASSINFO(wxFrame)) || - topWindow->IsKindOf(CLASSINFO(wxDialog)) ) - { - topWindow->Close(TRUE); - wxTheApp->DeletePendingObjects(); - } - else - { - delete topWindow; - wxTheApp->SetTopWindow(NULL); - } - } - - retValue = wxTheApp->OnExit(); - - wxEntryCleanup(); - - return retValue; - -#if wxUSE_ON_FATAL_EXCEPTION - } - __except ( gs_handleExceptions ? EXCEPTION_EXECUTE_HANDLER - : EXCEPTION_CONTINUE_SEARCH ) { - if ( wxTheApp ) - { - // give the user a chance to do something special about this - wxTheApp->OnFatalException(); - } - - ::ExitProcess(3); // the same exit code as abort() - - // NOTREACHED - } -#endif // wxUSE_ON_FATAL_EXCEPTION -} - -// restore warning state -#ifdef __VISUALC__ - #pragma warning(default: 4715) // not all control paths return a value -#endif // Visual C++ - -#else /* _WINDLL */ - -//---------------------------------------------------------------------- -// Entry point for wxWindows + the App in a DLL -//---------------------------------------------------------------------- - -int wxEntry(WXHINSTANCE hInstance) -{ - wxhInstance = (HINSTANCE) hInstance; - 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 - // for delayed, dynamic app object construction. - if (!wxTheApp) - { - wxCHECK_MSG( wxApp::GetInitializerFunction(), 0, - "No initializer - use IMPLEMENT_APP macro." ); - - wxTheApp = (* wxApp::GetInitializerFunction()) (); - } - - wxCHECK_MSG( wxTheApp, 0, "You have to define an instance of wxApp!" ); - - wxTheApp->argc = 0; - wxTheApp->argv = NULL; - - wxEntryInitGui(); - - wxTheApp->OnInit(); - - wxWindow *topWindow = wxTheApp->GetTopWindow(); - if ( topWindow && topWindow->GetHWND()) - { - topWindow->Show(TRUE); - } - - return 1; + wxAppBase::CleanUp(); } -#endif // _WINDLL -//// Static member initialization - -wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL; +// ---------------------------------------------------------------------------- +// wxApp ctor/dtor +// ---------------------------------------------------------------------------- wxApp::wxApp() { - argc = 0; - argv = NULL; m_printMode = wxPRINT_WINDOWS; - m_auto3D = TRUE; } wxApp::~wxApp() { - // Delete command-line args - int i; - for (i = 0; i < argc; i++) + // our cmd line arguments are allocated inside wxEntry(HINSTANCE), they + // don't come from main(), so we have to free them + + while ( argc ) { - delete[] argv[i]; + // m_argv elements were allocated by wxStrdup() + free(argv[--argc]); } - delete[] argv; + + // but m_argv itself -- using new[] + delete [] argv; } bool wxApp::Initialized() @@ -1150,21 +878,20 @@ bool wxApp::SendIdleEvents(wxWindow* win) return needMore; } -void wxApp::DeletePendingObjects() +void wxApp::WakeUpIdle() { - wxNode *node = wxPendingDelete.GetFirst(); - while (node) + // Send the top window a dummy message so idle handler processing will + // start up again. Doing it this way ensures that the idle handler + // wakes up in the right thread (see also wxWakeUpMainThread() which does + // the same for the main app thread only) + wxWindow *topWindow = wxTheApp->GetTopWindow(); + if ( topWindow ) { - wxObject *obj = node->GetData(); - - delete obj; - - if (wxPendingDelete.Member(obj)) - delete node; - - // Deleting one object may have deleted other pending - // objects, so start from beginning of list again. - node = wxPendingDelete.GetFirst(); + if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) ) + { + // should never happen + wxLogLastError(wxT("PostMessage(WM_NULL)")); + } } } @@ -1185,6 +912,17 @@ void wxApp::OnQueryEndSession(wxCloseEvent& event) } } +typedef struct _WXADllVersionInfo +{ + DWORD cbSize; + DWORD dwMajorVersion; // Major version + DWORD dwMinorVersion; // Minor version + DWORD dwBuildNumber; // Build number + DWORD dwPlatformID; // DLLVER_PLATFORM_* +} WXADLLVERSIONINFO; + +typedef HRESULT (CALLBACK* WXADLLGETVERSIONPROC)(WXADLLVERSIONINFO *); + /* static */ int wxApp::GetComCtl32Version() { @@ -1204,17 +942,25 @@ int wxApp::GetComCtl32Version() // do we have it? HMODULE hModuleComCtl32 = ::GetModuleHandle(wxT("COMCTL32")); + BOOL bFreeComCtl32 = FALSE ; + if(!hModuleComCtl32) + { + hModuleComCtl32 = ::LoadLibrary(wxT("COMCTL32.DLL")) ; + if(hModuleComCtl32) + { + bFreeComCtl32 = TRUE ; + } + } // if so, then we can check for the version if ( hModuleComCtl32 ) { // try to use DllGetVersion() if available in _headers_ - #ifdef DLLVER_PLATFORM_WINDOWS // defined in shlwapi.h - DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC) + WXADLLGETVERSIONPROC pfnDllGetVersion = (WXADLLGETVERSIONPROC) ::GetProcAddress(hModuleComCtl32, "DllGetVersion"); if ( pfnDllGetVersion ) { - DLLVERSIONINFO dvi; + WXADLLVERSIONINFO dvi; dvi.cbSize = sizeof(dvi); HRESULT hr = (*pfnDllGetVersion)(&dvi); @@ -1231,7 +977,6 @@ int wxApp::GetComCtl32Version() dvi.dwMinorVersion; } } - #endif // DllGetVersion() unavailable either during compile or // run-time, try to guess the version otherwise if ( !s_verComCtl32 ) @@ -1270,25 +1015,17 @@ int wxApp::GetComCtl32Version() } } } + + if(bFreeComCtl32) + { + ::FreeLibrary(hModuleComCtl32) ; + } } return s_verComCtl32; #endif } -void wxExit() -{ - if ( wxTheApp ) - { - wxTheApp->ExitMainLoop(); - } - else - { - // what else can we do? - exit(-1); - } -} - // Yield to incoming messages bool wxApp::Yield(bool onlyIfNeeded) @@ -1341,46 +1078,3 @@ bool wxApp::Yield(bool onlyIfNeeded) 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 use this function")); - - (void)doit; - return FALSE; -#endif -} - -//----------------------------------------------------------------------------- -// wxWakeUpIdle -//----------------------------------------------------------------------------- - -void wxWakeUpIdle() -{ - // Send the top window a dummy message so idle handler processing will - // start up again. Doing it this way ensures that the idle handler - // wakes up in the right thread (see also wxWakeUpMainThread() which does - // the same for the main app thread only) - wxWindow *topWindow = wxTheApp->GetTopWindow(); - if ( topWindow ) - { - if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) ) - { - // should never happen - wxLogLastError(wxT("PostMessage(WM_NULL)")); - } - } -} - -//----------------------------------------------------------------------------- - -// 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(__WINE__) && !defined(__TWIN32__) && !defined(WXMAKINGDLL)) -#include "main.cpp" -#endif