X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e2478fde622a16d25c66690af353dfdc37e7b582..cb73e6001f891ae46b12a1e4ca39b93649cb6099:/src/msw/app.cpp diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 1b2e4f96ba..ec3c4c0124 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -17,7 +17,7 @@ // headers // --------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "app.h" #endif @@ -49,9 +49,9 @@ #endif #include "wx/apptrait.h" -#include "wx/cmdline.h" #include "wx/filename.h" #include "wx/module.h" +#include "wx/dynlib.h" #include "wx/msw/private.h" @@ -85,38 +85,11 @@ #include #include -#if defined(__WIN95__) && !((defined(__GNUWIN32_OLD__) || defined(__WXMICROWIN__)) && !defined(__CYGWIN10__)) - #include -#endif - -#ifndef __WXMICROWIN__ -#include "wx/msw/msvcrt.h" -#endif - -// ---------------------------------------------------------------------------- -// conditional compilation -// ---------------------------------------------------------------------------- - -// The macro _WIN32_IE is defined by commctrl.h (unless it had already been -// defined before) and shows us what common control features are available -// during the compile time (it doesn't mean that they will be available during -// the run-time, use GetComCtl32Version() to test for them!). The possible -// values are: -// -// 0x0200 for comctl32.dll 4.00 shipped with Win95/NT 4.0 -// 0x0300 4.70 IE 3.x -// 0x0400 4.71 IE 4.0 -// 0x0401 4.72 IE 4.01 and Win98 -// 0x0500 5.00 IE 5.x and NT 5.0 (Win2000) - -#ifndef _WIN32_IE - // minimal set of features by default - #define _WIN32_IE 0x0200 -#endif +#include "wx/msw/wrapcctl.h" -#if _WIN32_IE >= 0x0300 && \ - (!defined(__MINGW32__) || wxCHECK_W32API_VERSION( 2, 0 )) && \ - !defined(__CYGWIN__) +#if (!defined(__MINGW32__) || wxCHECK_W32API_VERSION( 2, 0 )) && \ + !defined(__CYGWIN__) && !defined(__DIGITALMARS__) && !defined(__WXWINCE__) && \ + (!defined(_MSC_VER) || (_MSC_VER > 1100)) #include #endif @@ -124,9 +97,9 @@ // global variables // --------------------------------------------------------------------------- -extern wxChar *wxBuffer; extern wxList WXDLLEXPORT wxPendingDelete; -#ifndef __WXMICROWIN__ + +#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) extern void wxSetKeyboardHook(bool doIt); #endif @@ -141,31 +114,13 @@ 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; -LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM); +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- -// 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 +LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM); // =========================================================================== // wxGUIAppTraits implementation @@ -213,8 +168,8 @@ void *wxGUIAppTraits::BeforeChildWaitLoop() wxWindow *winActive = new wxFrame ( wxTheApp->GetTopWindow(), - -1, - _T(""), + wxID_ANY, + wxEmptyString, wxPoint(32600, 32600), wxSize(1, 1), wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR @@ -248,10 +203,28 @@ bool wxGUIAppTraits::DoMessageFromThreadWait() return !wxTheApp || wxTheApp->DoMessage(); } +wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo() +{ + static wxToolkitInfo info; + wxToolkitInfo& baseInfo = wxAppTraits::GetToolkitInfo(); + info.versionMajor = baseInfo.versionMajor; + info.versionMinor = baseInfo.versionMinor; + info.os = baseInfo.os; + info.shortName = _T("msw"); + info.name = _T("wxMSW"); +#ifdef __WXUNIVERSAL__ + info.shortName << _T("univ"); + info.name << _T("/wxUniversal"); +#endif + return info; +} + // =========================================================================== // wxApp implementation // =========================================================================== +int wxApp::m_nCmdShow = SW_SHOWNORMAL; + // --------------------------------------------------------------------------- // wxWin macros // --------------------------------------------------------------------------- @@ -264,14 +237,34 @@ 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 #if wxUSE_UNICODE && !wxUSE_UNICODE_MSLU - if ( wxGetOsVersion() != wxWINDOWS_NT ) + if ( wxGetOsVersion() != wxWINDOWS_NT && wxGetOsVersion() != wxWINDOWS_CE ) { // note that we can use MessageBoxW() as it's implemented even under // Win9x - OTOH, we can't use wxGetTranslation() because the file APIs @@ -279,7 +272,7 @@ bool wxApp::Initialize() ::MessageBox ( NULL, - _T("This program uses Unicode and requires Windows NT/2000/XP.\nProgram aborted."), + _T("This program uses Unicode and requires Windows NT/2000/XP/CE.\nProgram aborted."), _T("wxWindows Fatal Error"), MB_ICONERROR | MB_OK ); @@ -288,22 +281,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__ @@ -319,9 +296,14 @@ bool wxApp::Initialize() #if wxUSE_OLE // we need to initialize OLE library +#ifdef __WXWINCE__ + if ( FAILED(::CoInitializeEx(NULL, COINIT_MULTITHREADED)) ) + wxLogError(_("Cannot initialize OLE")); +#else if ( FAILED(::OleInitialize(NULL)) ) wxLogError(_("Cannot initialize OLE")); #endif +#endif #endif // wxUSE_OLE @@ -332,20 +314,9 @@ 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__ +#if defined(__WXMICROWIN__) && !defined(__WXWINCE__) // Create the brush for disabling bitmap buttons LOGBRUSH lb; @@ -373,14 +344,13 @@ bool wxApp::Initialize() if (wxDummyChar) wxDummyChar++; #endif -#ifndef __WXMICROWIN__ +#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) wxSetKeyboardHook(TRUE); #endif - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) - return FALSE; - return TRUE; + callBaseCleanup.Dismiss(); + + return true; } // --------------------------------------------------------------------------- @@ -525,81 +495,9 @@ 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__ +#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) wxSetKeyboardHook(FALSE); #endif @@ -607,296 +505,55 @@ 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 ); #if wxUSE_OLE +#ifdef __WXWINCE__ + ::CoUninitialize(); +#else ::OleUninitialize(); +#endif #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(); + wxWinHandleHash = NULL; - 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 + wxAppBase::CleanUp(); } -//---------------------------------------------------------------------- -// 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; - - 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; -} -#endif // _WINDLL - -//// Static member initialization +// ---------------------------------------------------------------------------- +// 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() @@ -1031,16 +688,6 @@ int wxApp::MainLoop() return s_currentMsg.wParam; } -// Returns TRUE if more time is needed. -bool wxApp::ProcessIdle() -{ - wxIdleEvent event; - event.SetEventObject(this); - ProcessEvent(event); - - return event.MoreRequested(); -} - void wxApp::ExitMainLoop() { // this will set m_keepGoing to FALSE a bit later @@ -1149,23 +796,8 @@ void wxApp::OnIdle(wxIdleEvent& event) return; wxIsInOnIdleFlag = 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::FlushActive(); -#endif // wxUSE_LOG + + wxAppBase::OnIdle(event); #if wxUSE_DC_CACHEING // automated DC cache management: clear the cached DCs and bitmap @@ -1175,56 +807,9 @@ void wxApp::OnIdle(wxIdleEvent& event) wxDC::ClearCache(); #endif // wxUSE_DC_CACHEING - // Send OnIdle events to all windows - if ( SendIdleEvents() ) - { - // SendIdleEvents() returns TRUE if at least one window requested more - // idle events - event.RequestMore(TRUE); - } - wxIsInOnIdleFlag = FALSE; } -// Send idle event to all top-level windows -bool wxApp::SendIdleEvents() -{ - bool needMore = FALSE; - - wxWindowList::Node* node = wxTopLevelWindows.GetFirst(); - while (node) - { - wxWindow* win = node->GetData(); - if (SendIdleEvents(win)) - needMore = TRUE; - node = node->GetNext(); - } - - return needMore; -} - -// Send idle event to window and all subwindows -bool wxApp::SendIdleEvents(wxWindow* win) -{ - wxIdleEvent event; - event.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event); - - bool needMore = event.MoreRequested(); - - wxWindowList::Node *node = win->GetChildren().GetFirst(); - while ( node ) - { - wxWindow *win = node->GetData(); - if (SendIdleEvents(win)) - needMore = TRUE; - - node = node->GetNext(); - } - - return needMore; -} - void wxApp::WakeUpIdle() { // Send the top window a dummy message so idle handler processing will @@ -1242,24 +827,6 @@ void wxApp::WakeUpIdle() } } -void wxApp::DeletePendingObjects() -{ - wxNode *node = wxPendingDelete.GetFirst(); - while (node) - { - 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(); - } -} - void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event)) { if (GetTopWindow()) @@ -1277,118 +844,90 @@ 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() { -#ifdef __WXMICROWIN__ +//FIX ME FOR DIGITALMARS!! +#if defined(__WXMICROWIN__) || defined(__WXWINCE__) || defined(__DIGITALMARS__) return 0; #else // cache the result + // + // NB: this is MT-ok as in the worst case we'd compute s_verComCtl32 twice, + // but as its value should be the same both times it doesn't matter static int s_verComCtl32 = -1; - wxCRIT_SECT_DECLARE(csComCtl32); - wxCRIT_SECT_LOCKER(lock, csComCtl32); - if ( s_verComCtl32 == -1 ) { // initally assume no comctl32.dll at all s_verComCtl32 = 0; + // we're prepared to handle the errors + wxLogNull noLog; + // do we have it? - HMODULE hModuleComCtl32 = ::GetModuleHandle(wxT("COMCTL32")); - BOOL bFreeComCtl32 = FALSE ; - if(!hModuleComCtl32) - { - hModuleComCtl32 = ::LoadLibrary(wxT("COMCTL32.DLL")) ; - if(hModuleComCtl32) - { - bFreeComCtl32 = TRUE ; - } - } + wxDynamicLibrary dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM); // if so, then we can check for the version - if ( hModuleComCtl32 ) + if ( dllComCtl32.IsLoaded() ) { +#ifdef DLLVER_PLATFORM_WINDOWS // try to use DllGetVersion() if available in _headers_ - WXADLLGETVERSIONPROC pfnDllGetVersion = (WXADLLGETVERSIONPROC) - ::GetProcAddress(hModuleComCtl32, "DllGetVersion"); - if ( pfnDllGetVersion ) + wxDYNLIB_FUNCTION( DLLGETVERSIONPROC, DllGetVersion, dllComCtl32 ); + if ( pfnDllGetVersion ) + { + DLLVERSIONINFO dvi; + dvi.cbSize = sizeof(dvi); + + HRESULT hr = (*pfnDllGetVersion)(&dvi); + if ( FAILED(hr) ) + { + wxLogApiError(_T("DllGetVersion"), hr); + } + else { - WXADLLVERSIONINFO dvi; - dvi.cbSize = sizeof(dvi); + // this is incompatible with _WIN32_IE values, but + // compatible with the other values returned by + // GetComCtl32Version() + s_verComCtl32 = 100*dvi.dwMajorVersion + + dvi.dwMinorVersion; + } + } +#endif - HRESULT hr = (*pfnDllGetVersion)(&dvi); - if ( FAILED(hr) ) - { - wxLogApiError(_T("DllGetVersion"), hr); - } - else - { - // this is incompatible with _WIN32_IE values, but - // compatible with the other values returned by - // GetComCtl32Version() - s_verComCtl32 = 100*dvi.dwMajorVersion + - dvi.dwMinorVersion; - } + // if DllGetVersion() is unavailable either during compile or + // run-time, try to guess the version otherwise + if ( !s_verComCtl32 ) + { + // InitCommonControlsEx is unique to 4.70 and later + void *pfn = dllComCtl32.GetSymbol(_T("InitCommonControlsEx")); + if ( !pfn ) + { + // not found, must be 4.00 + s_verComCtl32 = 400; } - // DllGetVersion() unavailable either during compile or - // run-time, try to guess the version otherwise - if ( !s_verComCtl32 ) + else // 4.70+ { - // InitCommonControlsEx is unique to 4.70 and later - FARPROC theProc = ::GetProcAddress - ( - hModuleComCtl32, - "InitCommonControlsEx" - ); - - if ( !theProc ) + // many symbols appeared in comctl32 4.71, could use any of + // them except may be DllInstall() + pfn = dllComCtl32.GetSymbol(_T("InitializeFlatSB")); + if ( !pfn ) { - // not found, must be 4.00 - s_verComCtl32 = 400; + // not found, must be 4.70 + s_verComCtl32 = 470; } else { - // many symbols appeared in comctl32 4.71, could use - // any of them except may be DllInstall - theProc = ::GetProcAddress - ( - hModuleComCtl32, - "InitializeFlatSB" - ); - if ( !theProc ) - { - // not found, must be 4.70 - s_verComCtl32 = 470; - } - else - { - // found, must be 4.71 - s_verComCtl32 = 471; - } + // found, must be 4.71 or later + s_verComCtl32 = 471; } } - } - - if(bFreeComCtl32) - { - ::FreeLibrary(hModuleComCtl32) ; + } } } return s_verComCtl32; -#endif +#endif // Microwin/!Microwin } // Yield to incoming messages @@ -1443,25 +982,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 -} - -//----------------------------------------------------------------------------- - -// 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(WXMAKINGDLL)) -#include "main.cpp" -#endif