WebViewEdge: Allow edge webview2 installation during runtime

Check if edge webview runtime is available in the call to
wxWebView::IsBackendAvailable() instead of only doing it during
process initialization. This allows an application to install
the Edge WebView2 Runtime during runtime and use the edge webview
afterwards without restarting the process.
This commit is contained in:
Tobias Taschner
2020-11-05 09:47:58 +01:00
parent 2d9c08e0cc
commit 46d123b953
6 changed files with 37 additions and 25 deletions

View File

@@ -65,7 +65,7 @@ public:
ICoreWebView2Settings* GetSettings();
static int ms_isAvailable;
static bool ms_isInitialized;
static wxDynamicLibrary ms_loaderDll;
static bool Initialize();

View File

@@ -122,10 +122,6 @@ public:
virtual void* GetNativeBackend() const wxOVERRIDE;
// ---- Edge-specific methods
static bool IsAvailable();
protected:
virtual void DoSetPage(const wxString& html, const wxString& baseUrl) wxOVERRIDE;
@@ -155,6 +151,7 @@ public:
{
return new wxWebViewEdge(parent, id, url, pos, size, style, name);
}
virtual bool IsAvailable() wxOVERRIDE;
};
#endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_EDGE && defined(__WXMSW__)

View File

@@ -119,6 +119,7 @@ public:
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxASCII_STR(wxWebViewNameStr)) = 0;
virtual bool IsAvailable() { return true; }
};
WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebViewFactory>, wxStringWebViewFactoryMap);

View File

@@ -220,6 +220,17 @@ public:
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxWebViewNameStr) = 0;
/**
Function to check if the backend is available at runtime. The
wxWebView implementation can use this function to check all
runtime requirements without trying to create a wxWebView.
@return returns @true if the backend can be used or @false if it is
not available during runtime.
@since 3.1.5
*/
virtual bool IsAvailable();
};
/**

View File

@@ -88,7 +88,10 @@ void wxWebView::RegisterFactory(const wxString& backend,
bool wxWebView::IsBackendAvailable(const wxString& backend)
{
wxStringWebViewFactoryMap::iterator iter = FindFactory(backend);
return iter != m_factoryMap.end();
if (iter != m_factoryMap.end())
return iter->second->IsAvailable();
else
return false;
}
// static
@@ -111,8 +114,7 @@ void wxWebView::InitFactoryMap()
#endif
#if wxUSE_WEBVIEW_EDGE
if (wxWebViewEdge::IsAvailable() &&
m_factoryMap.find(wxWebViewBackendEdge) == m_factoryMap.end())
if (m_factoryMap.find(wxWebViewBackendEdge) == m_factoryMap.end())
RegisterFactory(wxWebViewBackendEdge, wxSharedPtr<wxWebViewFactory>
(new wxWebViewFactoryEdge));
#endif

View File

@@ -51,7 +51,7 @@ typedef HRESULT(__stdcall *GetAvailableCoreWebView2BrowserVersionString_t)(
CreateCoreWebView2EnvironmentWithOptions_t wxCreateCoreWebView2EnvironmentWithOptions = NULL;
GetAvailableCoreWebView2BrowserVersionString_t wxGetAvailableCoreWebView2BrowserVersionString = NULL;
int wxWebViewEdgeImpl::ms_isAvailable = -1;
bool wxWebViewEdgeImpl::ms_isInitialized = false;
wxDynamicLibrary wxWebViewEdgeImpl::ms_loaderDll;
wxWebViewEdgeImpl::wxWebViewEdgeImpl(wxWebViewEdge* webview):
@@ -113,6 +113,9 @@ HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated(
bool wxWebViewEdgeImpl::Initialize()
{
if (ms_isInitialized)
return true;
if (!ms_loaderDll.Load("WebView2Loader.dll", wxDL_DEFAULT | wxDL_QUIET))
return false;
@@ -126,7 +129,10 @@ bool wxWebViewEdgeImpl::Initialize()
wxCoTaskMemPtr<wchar_t> versionStr;
HRESULT hr = wxGetAvailableCoreWebView2BrowserVersionString(NULL, &versionStr);
if (SUCCEEDED(hr) && versionStr)
{
ms_isInitialized = true;
return true;
}
else
wxLogApiError("GetCoreWebView2BrowserVersionInfo", hr);
@@ -135,10 +141,10 @@ bool wxWebViewEdgeImpl::Initialize()
void wxWebViewEdgeImpl::Uninitialize()
{
if (ms_isAvailable == 1)
if (ms_isInitialized)
{
ms_loaderDll.Unload();
ms_isAvailable = -1;
ms_isInitialized = false;
}
}
@@ -349,19 +355,6 @@ ICoreWebView2Settings* wxWebViewEdgeImpl::GetSettings()
return settings;
}
bool wxWebViewEdge::IsAvailable()
{
if (wxWebViewEdgeImpl::ms_isAvailable == -1)
{
if (!wxWebViewEdgeImpl::Initialize())
wxWebViewEdgeImpl::ms_isAvailable = 0;
else
wxWebViewEdgeImpl::ms_isAvailable = 1;
}
return wxWebViewEdgeImpl::ms_isAvailable == 1;
}
wxWebViewEdge::~wxWebViewEdge()
{
Unbind(wxEVT_SHOW, &wxWebViewEdge::OnShow, this);
@@ -376,7 +369,7 @@ bool wxWebViewEdge::Create(wxWindow* parent,
long style,
const wxString& name)
{
if (!IsAvailable())
if (!wxWebViewEdgeImpl::Initialize())
return false;
if (!wxControl::Create(parent, id, pos, size, style,
@@ -869,6 +862,14 @@ void wxWebViewEdge::DoSetPage(const wxString& html, const wxString& WXUNUSED(bas
m_impl->m_webView->NavigateToString(html.wc_str());
}
// wxWebViewFactoryEdge
bool wxWebViewFactoryEdge::IsAvailable()
{
return wxWebViewEdgeImpl::Initialize();
}
// ----------------------------------------------------------------------------
// Module ensuring all global/singleton objects are destroyed on shutdown.
// ----------------------------------------------------------------------------