X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b782f2e0f6abc7baa9a8bfc158847a89d5d12145..9fc3ad34c5326856aeebf02335244ae315cef688:/src/msw/app.cpp diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 5a67e7a4d6..0b947a5409 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -19,7 +19,6 @@ #ifdef __GNUG__ #pragma implementation "app.h" - #pragma implementation "appbase.h" #endif // For compilers that support precompilation, includes "wx.h". @@ -44,8 +43,8 @@ #include "wx/msgdlg.h" #include "wx/intl.h" #include "wx/dynarray.h" -# include "wx/wxchar.h" -# include "wx/icon.h" + #include "wx/wxchar.h" + #include "wx/icon.h" #endif #include "wx/log.h" @@ -98,14 +97,9 @@ extern wxChar *wxBuffer; extern wxChar *wxOsVersion; extern wxList *wxWinHandleList; extern wxList WXDLLEXPORT wxPendingDelete; -#if wxUSE_THREADS -extern wxList *wxPendingEvents; -extern wxCriticalSection *wxPendingEventsLocker; -#endif extern void wxSetKeyboardHook(bool doIt); extern wxCursor *g_globalCursor; -HINSTANCE wxhInstance = 0; MSG s_currentMsg; wxApp *wxTheApp = NULL; @@ -132,16 +126,12 @@ HICON wxDEFAULT_MDIPARENTFRAME_ICON = (HICON) NULL; 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 +LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM); #if wxUSE_RICHEDIT - static HINSTANCE gs_hRichEdit = (HINSTANCE) NULL; + // the handle to richedit DLL and the version of the DLL loaded + static HINSTANCE gs_hRichEdit = (HINSTANCE)NULL; + static int gs_verRichEdit = -1; #endif // =========================================================================== @@ -179,11 +169,8 @@ bool wxApp::Initialize() wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion); #endif - // I'm annoyed ... I don't know where to put this and I don't want to - // create a module for that as it's part of the core. #if wxUSE_THREADS - wxPendingEvents = new wxList(); - wxPendingEventsLocker = new wxCriticalSection(); + wxPendingEventsLocker = new wxCriticalSection; #endif wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); @@ -201,15 +188,6 @@ bool wxApp::Initialize() #if defined(__WIN95__) InitCommonControls(); -#if wxUSE_RICHEDIT - gs_hRichEdit = LoadLibrary(wxT("RICHED32.DLL")); - - if (gs_hRichEdit == (HINSTANCE) NULL) - { - wxLogError(_("Could not initialise Rich Edit DLL")); - } -#endif // wxUSE_RICHEDIT - #endif // __WIN95__ #if wxUSE_OLE @@ -234,6 +212,8 @@ bool wxApp::Initialize() g_globalCursor = new wxCursor; + // 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")); @@ -241,6 +221,7 @@ bool wxApp::Initialize() 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(); @@ -522,15 +503,11 @@ void wxApp::CleanUp() wxSetKeyboardHook(FALSE); -#ifdef __WIN95__ - #if wxUSE_RICHEDIT if (gs_hRichEdit != (HINSTANCE) NULL) FreeLibrary(gs_hRichEdit); #endif -#endif - #if wxUSE_PENWINDOWS wxCleanUpPenWin(); #endif @@ -563,10 +540,10 @@ void wxApp::CleanUp() if (wxWinHandleList) delete wxWinHandleList; - // GL: I'm annoyed ... I don't know where to put this and I don't want to + // GL: I'm annoyed ... I don't know where to put this and I don't want to // create a module for that as it's part of the core. -#if wxUSE_THREADS delete wxPendingEvents; +#if wxUSE_THREADS delete wxPendingEventsLocker; // If we don't do the following, we get an apparent memory leak. ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker(); @@ -628,7 +605,6 @@ int wxEntry(WXHINSTANCE hInstance, #else #undef CATCH_PROGRAM_EXCEPTIONS #endif - wxhInstance = (HINSTANCE) hInstance; if (!wxApp::Initialize()) @@ -656,6 +632,13 @@ int wxEntry(WXHINSTANCE hInstance, // but this call is provided for compatibility across platforms. wxTheApp->OnInitGui(); + // 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__ + wxLog::SetTimestamp(NULL); +#endif + int retValue = 0; if ( wxTheApp->OnInit() ) @@ -931,25 +914,6 @@ bool wxApp::ProcessIdle() return event.MoreRequested(); } -#if wxUSE_THREADS -void wxApp::ProcessPendingEvents() -{ - wxNode *node = wxPendingEvents->First(); - wxCriticalSectionLocker locker(*wxPendingEventsLocker); - - while (node) - { - wxEvtHandler *handler = (wxEvtHandler *)node->Data(); - - handler->ProcessPendingEvents(); - - delete node; - node = wxPendingEvents->First(); - } -} -#endif - - void wxApp::ExitMainLoop() { m_keepGoing = FALSE; @@ -983,7 +947,7 @@ bool wxApp::ProcessMessage(WXMSG *wxmsg) while ( hWnd && !wndThis ) { hWnd = ::GetParent(hWnd); - wndThis = wxFindWinFromHandle((WXHWND)hWnd); + wndThis = wxFindWinFromHandle((WXHWND)hWnd); } // Try translations first; find the youngest window with @@ -1032,10 +996,11 @@ void wxApp::OnIdle(wxIdleEvent& event) event.RequestMore(TRUE); } - // If they are pending events, we must process them. -#if wxUSE_THREADS + // If they are pending events, we must process them: pending events are + // either events to the threads other than main or events posted with + // wxPostEvent() functions ProcessPendingEvents(); -#endif + s_inOnIdle = FALSE; } @@ -1115,47 +1080,105 @@ void wxApp::OnQueryEndSession(wxCloseEvent& event) } } -int wxApp::GetComCtl32Version() const +#if wxUSE_RICHEDIT + +/* static */ +bool wxApp::InitRichEdit(int version) { - // have we loaded COMCTL32 yet? - HMODULE theModule = ::GetModuleHandle(wxT("COMCTL32")); - int version = 0; + wxCHECK_MSG( version >= 1 && version <= 3, FALSE, + _T("incorrect richedit control version requested") ); - // if so, then we can check for the version - if (theModule) + if ( version <= gs_verRichEdit ) { - // InitCommonControlsEx is unique to 4.7 and later - FARPROC theProc = ::GetProcAddress(theModule, "InitCommonControlsEx"); + // we've already got this or better + return TRUE; + } - if (! theProc) - { // not found, must be 4.00 - version = 400; - } - else + if ( gs_hRichEdit ) + { + ::FreeLibrary(gs_hRichEdit); + } + + // always try load riched20.dll first - like this we won't have to reload + // it later if we're first asked for RE 1 and then for RE 2 or 3 + wxString dllname = _T("riched20.dll"); + gs_hRichEdit = ::LoadLibrary(dllname); + if ( !gs_hRichEdit && (version == 1) ) + { + // fall back to RE 1 + dllname = _T("riched32.dll"); + gs_hRichEdit = ::LoadLibrary(dllname); + } + + if ( !gs_hRichEdit ) + { + wxLogSysError(_("Could not load Rich Edit DLL '%s'"), dllname.c_str()); + + gs_verRichEdit = -1; + + return FALSE; + } + + gs_verRichEdit = version; + + return TRUE; +} + +#endif // wxUSE_RICHEDIT + +/* static */ +int wxApp::GetComCtl32Version() +{ + // TODO should use DllGetVersion() instead of this hack + + // cache the result + static int s_verComCtl32 = -1; // MT-FIXME + + if ( s_verComCtl32 == -1 ) + { + s_verComCtl32 = 0; + + // have we loaded COMCTL32 yet? + HMODULE theModule = ::GetModuleHandle(wxT("COMCTL32")); + + // if so, then we can check for the version + if (theModule) { - // The following symbol are unique to 4.71 - // DllInstall - // FlatSB_EnableScrollBar FlatSB_GetScrollInfo FlatSB_GetScrollPos - // FlatSB_GetScrollProp FlatSB_GetScrollRange FlatSB_SetScrollInfo - // FlatSB_SetScrollPos FlatSB_SetScrollProp FlatSB_SetScrollRange - // FlatSB_ShowScrollBar - // _DrawIndirectImageList _DuplicateImageList - // InitializeFlatSB - // UninitializeFlatSB - // we could check for any of these - I chose DllInstall - FARPROC theProc = ::GetProcAddress(theModule, "DllInstall"); - if (! theProc) - { - // not found, must be 4.70 - version = 470; + // InitCommonControlsEx is unique to 4.7 and later + FARPROC theProc = ::GetProcAddress(theModule, + _T("InitCommonControlsEx")); + + if ( !theProc ) + { // not found, must be 4.00 + s_verComCtl32 = 400; } else - { // found, must be 4.71 - version = 471; + { + // The following symbol are unique to 4.71 + // DllInstall + // FlatSB_EnableScrollBar FlatSB_GetScrollInfo FlatSB_GetScrollPos + // FlatSB_GetScrollProp FlatSB_GetScrollRange FlatSB_SetScrollInfo + // FlatSB_SetScrollPos FlatSB_SetScrollProp FlatSB_SetScrollRange + // FlatSB_ShowScrollBar + // _DrawIndirectImageList _DuplicateImageList + // InitializeFlatSB + // UninitializeFlatSB + // we could check for any of these - I chose DllInstall + FARPROC theProc = ::GetProcAddress(theModule, _T("DllInstall")); + if ( !theProc ) + { + // not found, must be 4.70 + s_verComCtl32 = 470; + } + else + { // found, must be 4.71 + s_verComCtl32 = 471; + } } } } - return version; + + return s_verComCtl32; } void wxExit() @@ -1168,26 +1191,46 @@ void wxExit() // Yield to incoming messages bool wxYield() { + // we don't want to process WM_QUIT from here - it should be processed in + // the main event loop in order to stop it + MSG msg; - // We want to go back to the main message loop - // if we see a WM_QUIT. (?) -#ifdef __WXWINE__ - while (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_NOREMOVE) && msg.message != WM_QUIT) -#else - while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) && msg.message != WM_QUIT) -#endif + while ( PeekMessage(&msg, (HWND)0, 0, 0, PM_NOREMOVE) && + msg.message != WM_QUIT ) { if ( !wxTheApp->DoMessage() ) break; } + // If they are pending events, we must process them. -#if wxUSE_THREADS wxTheApp->ProcessPendingEvents(); -#endif return TRUE; } +//----------------------------------------------------------------------------- +// 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("PostMessage(WM_NULL)"); + } + } +} + +//----------------------------------------------------------------------------- + wxIcon wxApp::GetStdIcon(int which) const { @@ -1211,17 +1254,6 @@ wxApp::GetStdIcon(int which) const } } - -HINSTANCE wxGetInstance() -{ - return wxhInstance; -} - -void wxSetInstance(HINSTANCE hInst) -{ - wxhInstance = 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__))