mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Windows: Added WindowsWebView2WebBrowserComponent wrapper to add support for custom WebView2Loader.dll location and user data folder for WebView2
This commit is contained in:
parent
f5cb3f4ae1
commit
1f63357263
6 changed files with 139 additions and 23 deletions
|
|
@ -59,15 +59,15 @@
|
|||
|
||||
/** Config: JUCE_USE_WIN_WEBVIEW2
|
||||
Enables the use of the Microsoft Edge (Chromium) WebView2 browser on Windows,
|
||||
currently in developer preview. This requires Microsoft Edge (minimum version
|
||||
82.0.488.0) to be installed on the user's machine at runtime.
|
||||
currently in developer preview.
|
||||
|
||||
If using the Projucer, the Microsoft.Web.WebView2 package will be added to the
|
||||
project solution if this flag is enabled. If you are building using CMake you
|
||||
will need to manually add the package via the Visual Studio package manager.
|
||||
|
||||
If the required components are not available at runtime it will fall back to the
|
||||
IE-based Win32 web view.
|
||||
In addition to enabling this macro, you will need to use the
|
||||
WindowsWebView2WebBrowserComponent wrapper - see the documentation of that
|
||||
class for more details.
|
||||
*/
|
||||
#ifndef JUCE_USE_WIN_WEBVIEW2
|
||||
#define JUCE_USE_WIN_WEBVIEW2 0
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@ namespace juce
|
|||
A component that displays an embedded web browser.
|
||||
|
||||
The browser itself will be platform-dependent. On Mac and iOS it will be
|
||||
WebKit, on Android it will be Chrome, and on Linux it will be WebKit. On
|
||||
Windows, if the JUCE_USE_WIN_WEBVIEW2 flag is enabled, it will either be
|
||||
Microsoft Edge (Chromium) or IE depending on availability of the Edge
|
||||
runtime.
|
||||
WebKit, on Android it will be Chrome, and on Linux it will be WebKit.
|
||||
|
||||
On Windows it will be IE, but if JUCE_USE_WIN_WEBVIEW2 is enabled then using
|
||||
the WindowsWebView2WebBrowserComponent wrapper instead of this class directly
|
||||
will attempt to use the Microsoft Edge (Chromium) WebView2. See the documentation
|
||||
of that class for more information about its requirements.
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
|
|
@ -133,6 +135,13 @@ public:
|
|||
class Pimpl;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
friend class WindowsWebView2WebBrowserComponent;
|
||||
|
||||
explicit WebBrowserComponent (bool unloadPageWhenBrowserIsHidden,
|
||||
const File& dllLocation,
|
||||
const File& userDataFolder);
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<Pimpl> browser;
|
||||
bool blankPageShown = false, unloadPageWhenBrowserIsHidden;
|
||||
|
|
@ -146,6 +155,50 @@ private:
|
|||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebBrowserComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
If you have enabled the JUCE_USE_WIN_WEBVIEW2 flag then this wrapper will attempt to
|
||||
use the Microsoft Edge (Chromium) WebView2 control instead of IE on Windows. It will
|
||||
behave the same as WebBrowserComponent on all other platforms and will fall back to
|
||||
IE on Windows if the WebView2 requirements are not met.
|
||||
|
||||
This requires Microsoft Edge (minimum version 82.0.488.0) to be installed at runtime.
|
||||
|
||||
Currently this also requires that WebView2Loader.dll, which can be found in the
|
||||
Microsoft.Web.WebView package, is installed at runtime. As this is not a standard
|
||||
system DLL, we can't rely on it being found via the normal system DLL search paths.
|
||||
Therefore in order to use WebView2 you need to ensure that WebView2Loader.dll is
|
||||
installed either to a location covered by the Windows DLL system search paths or
|
||||
to the folder specified in the constructor of this class.
|
||||
*/
|
||||
class WindowsWebView2WebBrowserComponent : public WebBrowserComponent
|
||||
{
|
||||
public:
|
||||
/** Creates a WebBrowserComponent that is compatible with the WebView2 control
|
||||
on Windows.
|
||||
|
||||
This allows you to specify a custom location for the WebView2Loader.dll as
|
||||
well as a non-default location for storing user data for the browser instance.
|
||||
|
||||
@param unloadPageWhenBrowserIsHidden if this is true, then when the browser
|
||||
component is taken offscreen, it'll clear the current page
|
||||
and replace it with a blank page - this can be handy to stop
|
||||
the browser using resources in the background when it's not
|
||||
actually being used.
|
||||
@param dllLocation the path to WebView2Loader.dll, if this is empty then the default
|
||||
system DLL search paths will be used
|
||||
@param userDataFolder a directory in which the WebView2 user data will be stored, if
|
||||
this is empty then a directory will be created next to the
|
||||
executable
|
||||
*/
|
||||
explicit WindowsWebView2WebBrowserComponent (bool unloadPageWhenBrowserIsHidden = true,
|
||||
const File& dllLocation = {},
|
||||
const File& userDataFolder = {})
|
||||
: WebBrowserComponent (unloadPageWhenBrowserIsHidden, dllLocation, userDataFolder)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -585,6 +585,13 @@ WebBrowserComponent::WebBrowserComponent (const bool unloadWhenHidden)
|
|||
addAndMakeVisible (browser.get());
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File&,
|
||||
const File&)
|
||||
: WebBrowserComponent (unloadWhenHidden)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserComponent::~WebBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -898,9 +898,9 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_)
|
||||
WebBrowserComponent::WebBrowserComponent (const bool unloadWhenHidden)
|
||||
: browser (new Pimpl (*this)),
|
||||
unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_)
|
||||
unloadPageWhenBrowserIsHidden (unloadWhenHidden)
|
||||
{
|
||||
ignoreUnused (blankPageShown);
|
||||
ignoreUnused (unloadPageWhenBrowserIsHidden);
|
||||
|
|
@ -910,6 +910,13 @@ WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidd
|
|||
browser->init();
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File&,
|
||||
const File&)
|
||||
: WebBrowserComponent (unloadWhenHidden)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserComponent::~WebBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -543,6 +543,13 @@ WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden)
|
|||
addAndMakeVisible (browser.get());
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File&,
|
||||
const File&)
|
||||
: WebBrowserComponent (unloadWhenHidden)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserComponent::~WebBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -324,14 +324,14 @@ class WebView2 : public InternalWebViewType,
|
|||
public ComponentMovementWatcher
|
||||
{
|
||||
public:
|
||||
WebView2 (WebBrowserComponent& o)
|
||||
WebView2 (WebBrowserComponent& o, const File& dllLocation, const File& userDataFolder)
|
||||
: ComponentMovementWatcher (&o),
|
||||
owner (o)
|
||||
{
|
||||
if (! WinRTWrapper::getInstance()->isInitialised())
|
||||
throw std::runtime_error ("Failed to initialise the WinRT wrapper");
|
||||
|
||||
if (! createWebViewEnvironment())
|
||||
if (! createWebViewEnvironment (dllLocation, userDataFolder))
|
||||
throw std::runtime_error ("Failed to create the CoreWebView2Environemnt");
|
||||
|
||||
owner.addAndMakeVisible (this);
|
||||
|
|
@ -586,11 +586,32 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
bool createWebViewEnvironment()
|
||||
bool createWebViewEnvironment (const File& dllLocation, const File& userDataFolder)
|
||||
{
|
||||
using CreateWebViewEnvironmentWithOptionsFunc = HRESULT (*) (PCWSTR, PCWSTR,
|
||||
ICoreWebView2EnvironmentOptions*,
|
||||
ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler*);
|
||||
|
||||
auto dllPath = dllLocation.getFullPathName();
|
||||
|
||||
if (dllPath.isEmpty())
|
||||
dllPath = "WebView2Loader.dll";
|
||||
|
||||
auto loaderModule = LoadLibraryA (dllPath.toUTF8());
|
||||
auto* createWebViewEnvironmentWithOptions = (CreateWebViewEnvironmentWithOptionsFunc) GetProcAddress (loaderModule,
|
||||
"CreateCoreWebView2EnvironmentWithOptions");
|
||||
if (createWebViewEnvironmentWithOptions == nullptr)
|
||||
{
|
||||
// failed to load WebView2Loader.dll
|
||||
jassertfalse;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
|
||||
|
||||
auto hr = CreateCoreWebView2EnvironmentWithOptions (nullptr, nullptr, options.Get(),
|
||||
auto hr = createWebViewEnvironmentWithOptions (nullptr,
|
||||
userDataFolder != File() ? userDataFolder.getFullPathName().toWideCharPointer() : nullptr,
|
||||
options.Get(),
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[this] (HRESULT, ICoreWebView2Environment* env) -> HRESULT
|
||||
{
|
||||
|
|
@ -611,8 +632,15 @@ private:
|
|||
Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler> (
|
||||
[this] (HRESULT, ICoreWebView2Controller* controller) -> HRESULT
|
||||
{
|
||||
webViewController = controller;
|
||||
controller->get_CoreWebView2 (webView.resetAndGetPointerAddress());
|
||||
if (controller != nullptr)
|
||||
{
|
||||
webViewController = controller;
|
||||
controller->get_CoreWebView2(webView.resetAndGetPointerAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
isCreating = false;
|
||||
|
||||
|
|
@ -693,15 +721,20 @@ private:
|
|||
class WebBrowserComponent::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (WebBrowserComponent& owner)
|
||||
Pimpl (WebBrowserComponent& owner, const File& dllLocation, const File& userDataFolder, bool useWebView2)
|
||||
{
|
||||
#if JUCE_USE_WIN_WEBVIEW2
|
||||
try
|
||||
if (useWebView2)
|
||||
{
|
||||
internal.reset (new WebView2 (owner));
|
||||
#if JUCE_USE_WIN_WEBVIEW2
|
||||
try
|
||||
{
|
||||
internal.reset (new WebView2 (owner, dllLocation, userDataFolder));
|
||||
}
|
||||
catch (std::runtime_error&) {}
|
||||
#endif
|
||||
}
|
||||
catch (std::runtime_error&) {}
|
||||
#endif
|
||||
|
||||
ignoreUnused (dllLocation, userDataFolder);
|
||||
|
||||
if (internal == nullptr)
|
||||
internal.reset (new Win32WebView (owner));
|
||||
|
|
@ -718,7 +751,16 @@ private:
|
|||
|
||||
//==============================================================================
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden)
|
||||
: browser (new Pimpl (*this)),
|
||||
: browser (new Pimpl (*this, {}, {}, false)),
|
||||
unloadPageWhenBrowserIsHidden (unloadWhenHidden)
|
||||
{
|
||||
setOpaque (true);
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File& dllLocation,
|
||||
const File& userDataFolder)
|
||||
: browser (new Pimpl (*this, dllLocation, userDataFolder, true)),
|
||||
unloadPageWhenBrowserIsHidden (unloadWhenHidden)
|
||||
{
|
||||
setOpaque (true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue