From 4de8857c8586d2012435e2370ca2ddd54c5e1b65 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Jan 2021 00:10:10 +0100 Subject: [PATCH 1/2] Add wxDynamicLibrary::Attach() This is symmetric with Detach() and can be useful and doesn't cost anything to have. --- include/wx/dynlib.h | 3 +++ interface/wx/dynlib.h | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/wx/dynlib.h b/include/wx/dynlib.h index 1036771c06..93473b0add 100644 --- a/include/wx/dynlib.h +++ b/include/wx/dynlib.h @@ -242,6 +242,9 @@ public: // library couldn't be loaded but simply returns NULL static wxDllType RawLoad(const wxString& libname, int flags = wxDL_DEFAULT); + // attach to an existing handle + void Attach(wxDllType h) { Unload(); m_handle = h; } + // detach the library object from its handle, i.e. prevent the object from // unloading the library in its dtor -- the caller is now responsible for // doing this diff --git a/interface/wx/dynlib.h b/interface/wx/dynlib.h index 93cb2ef2e1..991642c700 100644 --- a/interface/wx/dynlib.h +++ b/interface/wx/dynlib.h @@ -147,9 +147,23 @@ public: wxPluginCategory cat = wxDL_PLUGIN_GUI); /** - Detaches this object from its library handle, i.e.\ the object will not - unload the library any longer in its destructor but it is now the - callers responsibility to do this using Unload(). + Attaches the object to an existing handle. + + This allows to give ownership of an existing handle, possibly obtained + from Detach(), to this object, so that it will unload it when destroyed. + + @since 3.1.5 + */ + void Attach(wxDllType h); + + /** + Detaches this object from its library handle. + + This means that the object will not unload the library any longer in + its destructor but it is now the callers responsibility to do this + using static Unload(). + + @see Attach() */ wxDllType Detach(); From bc825de1fe5c5323358242cdf9ea57bee4b8139e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Jan 2021 00:10:32 +0100 Subject: [PATCH 2/2] Simplify and make more robust wxWebViewEdge initialization Get rid of ms_isInitialized as it must be kept synchronized with ms_loaderDll.IsLoaded() anyhow, and it's simpler to not have it at all rather than ensuring this. Also ensure that calling Initialize() again, after doing it first unsuccessfully, doesn't assert because ms_loaderDll is already loaded, by only leaving it with a valid handle if the initialization succeeded. Closes #19041. --- include/wx/msw/private/webview_edge.h | 1 - src/msw/webview_edge.cpp | 28 ++++++++++++--------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/include/wx/msw/private/webview_edge.h b/include/wx/msw/private/webview_edge.h index 765127e9ed..3fb204309c 100644 --- a/include/wx/msw/private/webview_edge.h +++ b/include/wx/msw/private/webview_edge.h @@ -65,7 +65,6 @@ public: ICoreWebView2Settings* GetSettings(); - static bool ms_isInitialized; static wxDynamicLibrary ms_loaderDll; static bool Initialize(); diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 13e5af4bb6..74694fa8d9 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -51,7 +51,6 @@ typedef HRESULT(__stdcall *GetAvailableCoreWebView2BrowserVersionString_t)( CreateCoreWebView2EnvironmentWithOptions_t wxCreateCoreWebView2EnvironmentWithOptions = NULL; GetAvailableCoreWebView2BrowserVersionString_t wxGetAvailableCoreWebView2BrowserVersionString = NULL; -bool wxWebViewEdgeImpl::ms_isInitialized = false; wxDynamicLibrary wxWebViewEdgeImpl::ms_loaderDll; wxWebViewEdgeImpl::wxWebViewEdgeImpl(wxWebViewEdge* webview): @@ -113,39 +112,36 @@ HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated( bool wxWebViewEdgeImpl::Initialize() { - if (ms_isInitialized) + if (ms_loaderDll.IsLoaded()) return true; - if (!ms_loaderDll.Load("WebView2Loader.dll", wxDL_DEFAULT | wxDL_QUIET)) + wxDynamicLibrary loaderDll; + if (!loaderDll.Load("WebView2Loader.dll", wxDL_DEFAULT | wxDL_QUIET)) return false; // Try to load functions from loader DLL - wxDL_INIT_FUNC(wx, CreateCoreWebView2EnvironmentWithOptions, ms_loaderDll); - wxDL_INIT_FUNC(wx, GetAvailableCoreWebView2BrowserVersionString, ms_loaderDll); + wxDL_INIT_FUNC(wx, CreateCoreWebView2EnvironmentWithOptions, loaderDll); + wxDL_INIT_FUNC(wx, GetAvailableCoreWebView2BrowserVersionString, loaderDll); if (!wxGetAvailableCoreWebView2BrowserVersionString || !wxCreateCoreWebView2EnvironmentWithOptions) return false; // Check if a Edge browser can be found by the loader DLL wxCoTaskMemPtr versionStr; HRESULT hr = wxGetAvailableCoreWebView2BrowserVersionString(NULL, &versionStr); - if (SUCCEEDED(hr) && versionStr) + if (FAILED(hr) || !versionStr) { - ms_isInitialized = true; - return true; - } - else wxLogApiError("GetCoreWebView2BrowserVersionInfo", hr); + return false; + } - return false; + ms_loaderDll.Attach(loaderDll.Detach()); + + return true; } void wxWebViewEdgeImpl::Uninitialize() { - if (ms_isInitialized) - { - ms_loaderDll.Unload(); - ms_isInitialized = false; - } + ms_loaderDll.Unload(); } void wxWebViewEdgeImpl::UpdateBounds()