diff --git a/include/wx/dynlib.h b/include/wx/dynlib.h index 5627882585..3bf267f4c8 100644 --- a/include/wx/dynlib.h +++ b/include/wx/dynlib.h @@ -76,6 +76,18 @@ enum wxDLFlags wxDL_NOSHARE = 0x00000010, // load new DLL, don't reuse already loaded // (only for wxPluginManager) + wxDL_QUIET = 0x00000020, // don't log an error if failed to load + +#if wxABI_VERSION >= 20810 + // this flag is dangerous, for internal use of wxMSW only, don't use at all + // and especially don't use directly, use wxLoadedDLL instead if you really + // do need it + wxDL_GET_LOADED = 0x00000040, // Win32 only: return handle of already + // loaded DLL or NULL otherwise; Unload() + // should not be called so don't forget to + // Detach() if you use this function +#endif // wx 2.8.10+ + wxDL_DEFAULT = wxDL_NOW // default flags correspond to Win32 }; @@ -309,6 +321,28 @@ protected: DECLARE_NO_COPY_CLASS(wxDynamicLibrary) }; +#if defined(__WXMSW__) && wxABI_VERSION >= 20810 + +// ---------------------------------------------------------------------------- +// wxLoadedDLL is a MSW-only internal helper class allowing to dynamically bind +// to a DLL already loaded into the project address space +// ---------------------------------------------------------------------------- + +class wxLoadedDLL : public wxDynamicLibrary +{ +public: + wxLoadedDLL(const wxString& dllname) + : wxDynamicLibrary(dllname, wxDL_GET_LOADED | wxDL_VERBATIM | wxDL_QUIET) + { + } + + ~wxLoadedDLL() + { + Detach(); + } +}; + +#endif // __WXMSW__ // ---------------------------------------------------------------------------- // Interesting defines diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 461f3a2b6d..658bf10089 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -611,8 +611,16 @@ int wxApp::GetComCtl32Version() wxLogNull noLog; #if wxUSE_DYNLIB_CLASS - // do we have it? - wxDynamicLibrary dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM); + // we don't want to load comctl32.dll, it should be already loaded but, + // depending on the OS version and the presence of the manifest, it can + // be either v5 or v6 and instead of trying to guess it just get the + // handle of the already loaded version + wxLoadedDLL dllComCtl32(_T("comctl32.dll")); + if ( !dllComCtl32.IsLoaded() ) + { + s_verComCtl32 = 0; + return 0; + } // if so, then we can check for the version if ( dllComCtl32.IsLoaded() ) @@ -668,7 +676,7 @@ int wxApp::GetComCtl32Version() } } } -#endif +#endif // wxUSE_DYNLIB_CLASS } return s_verComCtl32; diff --git a/src/msw/dlmsw.cpp b/src/msw/dlmsw.cpp index 923a2b5144..fd50a46e24 100644 --- a/src/msw/dlmsw.cpp +++ b/src/msw/dlmsw.cpp @@ -276,9 +276,11 @@ wxDllType wxDynamicLibrary::GetProgramHandle() /* static */ wxDllType -wxDynamicLibrary::RawLoad(const wxString& libname, int WXUNUSED(flags)) +wxDynamicLibrary::RawLoad(const wxString& libname, int flags) { - return ::LoadLibrary(libname); + return flags & wxDL_GET_LOADED + ? ::GetModuleHandle(libname) + : ::LoadLibrary(libname); } /* static */ diff --git a/src/msw/window.cpp b/src/msw/window.cpp index d8284a26ed..1fb2960a89 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -5180,9 +5180,9 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) static bool s_initDone = false; if ( !s_initDone ) { - wxLogNull noLog; - - wxDynamicLibrary dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM); + // see comment in wxApp::GetComCtl32Version() explaining the + // use of wxLoadedDLL + wxLoadedDLL dllComCtl32(_T("comctl32.dll")); if ( dllComCtl32.IsLoaded() ) { s_pfn_TrackMouseEvent = (_TrackMouseEvent_t) @@ -5190,10 +5190,6 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) } s_initDone = true; - - // notice that it's ok to unload comctl32.dll here as it won't - // be really unloaded, being still in use because we link to it - // statically too } if ( s_pfn_TrackMouseEvent )