1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Added WinRT web view

This commit is contained in:
ed 2020-03-25 12:06:19 +00:00
parent 4e7eb0875b
commit 8f3b9036d6
7 changed files with 662 additions and 59 deletions

View file

@ -63,9 +63,8 @@
/** Config: JUCE_USE_WINRT_MIDI
Enables the use of the Windows Runtime API for MIDI, allowing connections
to Bluetooth Low Energy devices on Windows 10 version 1809 (October 2018
Update) and later. If you enable this flag then older, unsupported,
versions of Windows will automatically fall back to using the regular
Win32 MIDI API.
Update) and later. If you enable this flag then older versions of Windows
will automatically fall back to using the regular Win32 MIDI API.
You will need version 10.0.14393.0 of the Windows Standalone SDK to compile
and you may need to add the path to the WinRT headers. The path to the

View file

@ -35,7 +35,7 @@
#define JUCE_CORE_INCLUDE_COM_SMART_PTR 1
#define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1
#if JUCE_USE_WINRT_MIDI
#if JUCE_USE_WINRT_MIDI || JUCE_USE_WINRT_WEBVIEW
#define JUCE_EVENTS_INCLUDE_WINRT_WRAPPER 1
#endif

View file

@ -59,7 +59,7 @@
#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0
#endif
#if JUCE_EVENTS_INCLUDE_WINRT_WRAPPER && JUCE_WINDOWS
#if JUCE_WINDOWS && JUCE_EVENTS_INCLUDE_WINRT_WRAPPER
// If this header file is missing then you are probably attempting to use WinRT
// functionality without the WinRT libraries installed on your system. Try installing
// the latest Windows Standalone SDK and maybe also adding the path to the WinRT

View file

@ -51,6 +51,7 @@ public:
~ComPtr() { release(); }
operator ComClass*() const noexcept { return p; }
ComClass* get() const noexcept { return p; }
ComClass& operator*() const noexcept { return *p; }
ComClass* operator->() const noexcept { return p; }

View file

@ -32,6 +32,10 @@
#define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1
#define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1
#if JUCE_USE_WINRT_WEBVIEW
#define JUCE_EVENTS_INCLUDE_WINRT_WRAPPER 1
#endif
#ifndef JUCE_PUSH_NOTIFICATIONS
#define JUCE_PUSH_NOTIFICATIONS 0
#endif
@ -78,6 +82,18 @@
#if JUCE_WEB_BROWSER
#include <exdisp.h>
#include <exdispid.h>
#if JUCE_USE_WINRT_WEBVIEW
#include <windows.web.ui.h>
#include <windows.web.ui.interop.h>
#include <windows.foundation.h>
#include <windows.foundation.collections.h>
#pragma warning (push)
#pragma warning (disable: 4265)
#include <wrl.h>
#include <wrl/wrappers/corewrappers.h>
#pragma warning (pop)
#endif
#endif
//==============================================================================

View file

@ -56,6 +56,21 @@
#define JUCE_WEB_BROWSER 1
#endif
/** Config: JUCE_USE_WINRT_WEBVIEW
Enables the use of the EdgeHTML browser engine on Windows. This will use
the Windows Runtime API on Windows 10 version 1809 (October 2018 Update)
and later. If you enable this flag then older versions of Windows will
automatically fall back to using the regualar Win32 web view.
You will need version 10.0.14393.0 of the Windows Standalone SDK to compile
and you may need to add the path to the WinRT headers. The path to the
headers will be something similar to
"C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\winrt".
*/
#ifndef JUCE_USE_WINRT_WEBVIEW
#define JUCE_USE_WINRT_WEBVIEW 0
#endif
/** Config: JUCE_ENABLE_LIVE_CONSTANT_EDITOR
This lets you turn on the JUCE_ENABLE_LIVE_CONSTANT_EDITOR support (desktop only). By default
this will be enabled for debug builds and disabled for release builds. See the documentation

View file

@ -19,6 +19,27 @@
namespace juce
{
struct InternalWebViewType
{
InternalWebViewType() {}
virtual ~InternalWebViewType() {}
virtual void createBrowser() = 0;
virtual bool hasBrowserBeenCreated() = 0;
virtual void goToURL (const String&, const StringArray*, const MemoryBlock*) = 0;
virtual void stop() = 0;
virtual void goBack() = 0;
virtual void goForward() = 0;
virtual void refresh() = 0;
virtual void focusGained() {}
virtual void setWebViewSize (int, int) = 0;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InternalWebViewType)
};
#if JUCE_MINGW
JUCE_DECLARE_UUID_GETTER (IOleClientSite, "00000118-0000-0000-c000-000000000046")
JUCE_DECLARE_UUID_GETTER (IDispatch, "00020400-0000-0000-c000-000000000046")
@ -33,12 +54,17 @@ JUCE_DECLARE_UUID_GETTER (IConnectionPointContainer, "B196B284-BAB4-101A-B69C-00
JUCE_DECLARE_UUID_GETTER (IWebBrowser2, "D30C1661-CDAF-11D0-8A3E-00C04FC9E26E")
JUCE_DECLARE_UUID_GETTER (WebBrowser, "8856F961-340A-11D0-A96B-00C04FD705A2")
class WebBrowserComponent::Pimpl : public ActiveXControlComponent
//==============================================================================
class Win32WebView : public InternalWebViewType,
public ActiveXControlComponent
{
public:
Pimpl() {}
Win32WebView (WebBrowserComponent& owner)
{
owner.addAndMakeVisible (this);
}
~Pimpl()
~Win32WebView() override
{
if (connectionPoint != nullptr)
connectionPoint->Unadvise (adviseCookie);
@ -47,7 +73,7 @@ public:
browser->Release();
}
void createBrowser()
void createBrowser() override
{
auto webCLSID = __uuidof (WebBrowser);
createControl (&webCLSID);
@ -63,7 +89,7 @@ public:
if (connectionPoint != nullptr)
{
auto* owner = dynamic_cast<WebBrowserComponent*> (getParentComponent());
auto* owner = dynamic_cast<WebBrowserComponent*> (Component::getParentComponent());
jassert (owner != nullptr);
auto handler = new EventHandler (*owner);
@ -73,9 +99,12 @@ public:
}
}
void goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
bool hasBrowserBeenCreated() override
{
return browser != nullptr;
}
void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) override
{
if (browser != nullptr)
{
@ -132,10 +161,63 @@ public:
}
}
//==============================================================================
IWebBrowser2* browser = nullptr;
void stop() override
{
if (browser != nullptr)
browser->Stop();
}
void goBack() override
{
if (browser != nullptr)
browser->GoBack();
}
void goForward() override
{
if (browser != nullptr)
browser->GoForward();
}
void refresh() override
{
if (browser != nullptr)
browser->Refresh();
}
void focusGained() override
{
auto iidOleObject = __uuidof (IOleObject);
auto iidOleWindow = __uuidof (IOleWindow);
if (auto oleObject = (IOleObject*) queryInterface (&iidOleObject))
{
if (auto oleWindow = (IOleWindow*) queryInterface (&iidOleWindow))
{
IOleClientSite* oleClientSite = nullptr;
if (SUCCEEDED (oleObject->GetClientSite (&oleClientSite)))
{
HWND hwnd;
oleWindow->GetWindow (&hwnd);
oleObject->DoVerb (OLEIVERB_UIACTIVATE, nullptr, oleClientSite, 0, hwnd, nullptr);
oleClientSite->Release();
}
oleWindow->Release();
}
oleObject->Release();
}
}
void setWebViewSize (int width, int height) override
{
setSize (width, height);
}
private:
IWebBrowser2* browser = nullptr;
IConnectionPoint* connectionPoint = nullptr;
DWORD adviseCookie = 0;
@ -226,19 +308,534 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EventHandler)
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
};
#if JUCE_USE_WINRT_WEBVIEW
extern RTL_OSVERSIONINFOW getWindowsVersionInfo();
using namespace Microsoft::WRL;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Storage::Streams;
using namespace ABI::Windows::Web;
using namespace ABI::Windows::Web::UI;
using namespace ABI::Windows::Web::UI::Interop;
using namespace ABI::Windows::Web::Http;
using namespace ABI::Windows::Web::Http::Headers;
//==============================================================================
WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_)
: browser (new Pimpl()),
blankPageShown (false),
unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_)
class WinRTWebView : public InternalWebViewType,
public Component,
public ComponentMovementWatcher
{
public:
WinRTWebView (WebBrowserComponent& o)
: ComponentMovementWatcher (&o),
owner (o)
{
if (! WinRTWrapper::getInstance()->isInitialised())
throw std::runtime_error ("Failed to initialise the WinRT wrapper");
if (! createWebViewProcess())
throw std::runtime_error ("Failed to create the WebViewControlProcess");
owner.addAndMakeVisible (this);
}
~WinRTWebView() override
{
if (webViewControl != nullptr)
webViewControl->Stop();
removeEventHandlers();
webViewProcess->Terminate();
}
void createBrowser() override
{
if (webViewControl == nullptr)
createWebViewControl();
}
bool hasBrowserBeenCreated() override
{
return webViewControl != nullptr || isCreating;
}
void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) override
{
if (webViewControl != nullptr)
{
if ((headers != nullptr && ! headers->isEmpty())
|| (postData != nullptr && postData->getSize() > 0))
{
auto requestMessage = createHttpRequestMessage (url, headers, postData);
webViewControl->NavigateWithHttpRequestMessage (requestMessage.get());
}
else
{
auto uri = createURI (url);
webViewControl->Navigate (uri.get());
}
}
}
void stop() override
{
if (webViewControl != nullptr)
webViewControl->Stop();
}
void goBack() override
{
if (webViewControl != nullptr)
{
boolean canGoBack = false;
webViewControl->get_CanGoBack (&canGoBack);
if (canGoBack)
webViewControl->GoBack();
}
}
void goForward() override
{
if (webViewControl != nullptr)
{
boolean canGoForward = false;
webViewControl->get_CanGoForward (&canGoForward);
if (canGoForward)
webViewControl->GoForward();
}
}
void refresh() override
{
if (webViewControl != nullptr)
webViewControl->Refresh();
}
void setWebViewSize (int width, int height) override
{
setSize (width, height);
}
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override
{
if (auto* peer = owner.getTopLevelComponent()->getPeer())
setControlBounds (peer->getAreaCoveredBy (owner));
}
void componentPeerChanged() override
{
componentMovedOrResized (true, true);
}
void componentVisibilityChanged() override
{
setControlVisible (owner.isShowing());
componentPeerChanged();
owner.visibilityChanged();
}
private:
//==============================================================================
template<typename OperationResultType, typename ResultsType>
static HRESULT waitForCompletion (IAsyncOperation<OperationResultType>* op, ResultsType* results)
{
using OperationType = IAsyncOperation<OperationResultType>;
using DelegateType = IAsyncOperationCompletedHandler<OperationResultType>;
struct EventDelegate : public RuntimeClass<RuntimeClassFlags<RuntimeClassType::Delegate>,
DelegateType,
FtmBase>
{
EventDelegate() = default;
~EventDelegate()
{
CloseHandle (eventCompleted);
}
HRESULT RuntimeClassInitialize()
{
eventCompleted = CreateEventEx (nullptr, nullptr, 0, EVENT_ALL_ACCESS);
return eventCompleted == nullptr ? HRESULT_FROM_WIN32 (GetLastError()) : S_OK;
}
HRESULT Invoke (OperationType*, AsyncStatus newStatus)
{
status = newStatus;
SetEvent (eventCompleted);
return S_OK;
}
AsyncStatus status = AsyncStatus::Started;
HANDLE eventCompleted = nullptr;
};
WinRTWrapper::ComPtr<OperationType> operation = op;
WinRTWrapper::ComPtr<EventDelegate> eventCallback;
auto hr = MakeAndInitialize<EventDelegate> (eventCallback.resetAndGetPointerAddress());
if (SUCCEEDED (hr))
{
hr = operation->put_Completed (eventCallback.get());
if (SUCCEEDED (hr))
{
HANDLE waitForEvents[1] { eventCallback->eventCompleted };
auto handleCount = (ULONG) ARRAYSIZE (waitForEvents);
DWORD handleIndex = 0;
hr = CoWaitForMultipleHandles (COWAIT_DISPATCH_WINDOW_MESSAGES | COWAIT_DISPATCH_CALLS | COWAIT_INPUTAVAILABLE,
INFINITE, handleCount, waitForEvents, &handleIndex);
if (SUCCEEDED (hr))
{
if (eventCallback->status == AsyncStatus::Completed)
{
hr = operation->GetResults (results);
}
else
{
WinRTWrapper::ComPtr<IAsyncInfo> asyncInfo;
if (SUCCEEDED (operation->QueryInterface (asyncInfo.resetAndGetPointerAddress())))
asyncInfo->get_ErrorCode (&hr);
}
}
}
}
return hr;
}
//==============================================================================
template<class ArgsType>
String getURIStringFromArgs (ArgsType& args)
{
WinRTWrapper::ComPtr<IUriRuntimeClass> uri;
args.get_Uri (uri.resetAndGetPointerAddress());
if (uri != nullptr)
{
HSTRING uriString;
uri->get_AbsoluteUri (&uriString);
return WinRTWrapper::getInstance()->hStringToString (uriString);
}
return {};
}
void addEventHandlers()
{
if (webViewControl != nullptr)
{
webViewControl->add_NavigationStarting (Callback<ITypedEventHandler<IWebViewControl*, WebViewControlNavigationStartingEventArgs*>> (
[this] (IWebViewControl*, IWebViewControlNavigationStartingEventArgs* args)
{
auto uriString = getURIStringFromArgs (*args);
if (uriString.isNotEmpty())
args->put_Cancel (! owner.pageAboutToLoad (uriString));
return S_OK;
}
).Get(), &navigationStartingToken);
webViewControl->add_NewWindowRequested (Callback<ITypedEventHandler<IWebViewControl*, WebViewControlNewWindowRequestedEventArgs*>> (
[this] (IWebViewControl*, IWebViewControlNewWindowRequestedEventArgs* args)
{
auto uriString = getURIStringFromArgs (*args);
if (uriString.isNotEmpty())
{
owner.newWindowAttemptingToLoad (uriString);
args->put_Handled (true);
}
return S_OK;
}
).Get(), &newWindowRequestedToken);
webViewControl->add_NavigationCompleted (Callback<ITypedEventHandler<IWebViewControl*, WebViewControlNavigationCompletedEventArgs*>> (
[this] (IWebViewControl*, IWebViewControlNavigationCompletedEventArgs* args)
{
auto uriString = getURIStringFromArgs (*args);
if (uriString.isNotEmpty())
{
boolean success;
args->get_IsSuccess (&success);
if (success)
{
owner.pageFinishedLoading (uriString);
}
else
{
WebErrorStatus status;
args->get_WebErrorStatus (&status);
owner.pageLoadHadNetworkError ("Error code: " + String (status));
}
}
return S_OK;
}
).Get(), &navigationCompletedToken);
}
}
void removeEventHandlers()
{
if (webViewControl != nullptr)
{
if (navigationStartingToken.value != 0)
webViewControl->remove_NavigationStarting (navigationStartingToken);
if (newWindowRequestedToken.value != 0)
webViewControl->remove_NewWindowRequested (newWindowRequestedToken);
if (navigationCompletedToken.value != 0)
webViewControl->remove_NavigationCompleted (navigationCompletedToken);
}
}
bool createWebViewProcess()
{
auto webViewControlProcessFactory
= WinRTWrapper::getInstance()->getWRLFactory<IWebViewControlProcessFactory> (RuntimeClass_Windows_Web_UI_Interop_WebViewControlProcess);
if (webViewControlProcessFactory == nullptr)
{
jassertfalse;
return false;
}
auto webViewProcessOptions
= WinRTWrapper::getInstance()->activateInstance<IWebViewControlProcessOptions> (RuntimeClass_Windows_Web_UI_Interop_WebViewControlProcessOptions,
__uuidof (IWebViewControlProcessOptions));
webViewProcessOptions->put_PrivateNetworkClientServerCapability (WebViewControlProcessCapabilityState_Enabled);
webViewControlProcessFactory->CreateWithOptions (webViewProcessOptions.get(), webViewProcess.resetAndGetPointerAddress());
return webViewProcess != nullptr;
}
void createWebViewControl()
{
if (auto* peer = getPeer())
{
ScopedValueSetter<bool> svs (isCreating, true);
WinRTWrapper::ComPtr<IAsyncOperation<WebViewControl*>> createWebViewAsyncOperation;
webViewProcess->CreateWebViewControlAsync ((INT64) peer->getNativeHandle(), {},
createWebViewAsyncOperation.resetAndGetPointerAddress());
waitForCompletion (createWebViewAsyncOperation.get(), webViewControl.resetAndGetPointerAddress());
addEventHandlers();
componentMovedOrResized (true, true);
}
}
//==============================================================================
WinRTWrapper::ComPtr<IUriRuntimeClass> createURI (const String& url)
{
auto uriRuntimeFactory
= WinRTWrapper::getInstance()->getWRLFactory <IUriRuntimeClassFactory> (RuntimeClass_Windows_Foundation_Uri);
if (uriRuntimeFactory == nullptr)
{
jassertfalse;
return {};
}
WinRTWrapper::ScopedHString hstr (url);
WinRTWrapper::ComPtr<IUriRuntimeClass> uriRuntimeClass;
uriRuntimeFactory->CreateUri (hstr.get(), uriRuntimeClass.resetAndGetPointerAddress());
return uriRuntimeClass;
}
WinRTWrapper::ComPtr<IHttpContent> getPOSTContent (const MemoryBlock& postData)
{
auto factory = WinRTWrapper::getInstance()->getWRLFactory<IHttpStringContentFactory> (RuntimeClass_Windows_Web_Http_HttpStringContent);
if (factory == nullptr)
{
jassertfalse;
return {};
}
WinRTWrapper::ScopedHString hStr (postData.toString());
WinRTWrapper::ComPtr<IHttpContent> content;
factory->CreateFromString (hStr.get(), content.resetAndGetPointerAddress());
return content;
}
WinRTWrapper::ComPtr<IHttpMethod> getMethod (bool isPOST)
{
auto methodFactory = WinRTWrapper::getInstance()->getWRLFactory<IHttpMethodStatics> (RuntimeClass_Windows_Web_Http_HttpMethod);
if (methodFactory == nullptr)
{
jassertfalse;
return {};
}
WinRTWrapper::ComPtr<IHttpMethod> method;
if (isPOST)
methodFactory->get_Post (method.resetAndGetPointerAddress());
else
methodFactory->get_Get (method.resetAndGetPointerAddress());
return method;
}
void addHttpHeaders (WinRTWrapper::ComPtr<IHttpRequestMessage>& requestMessage, const StringArray& headers)
{
WinRTWrapper::ComPtr<IHttpRequestHeaderCollection> headerCollection;
requestMessage->get_Headers (headerCollection.resetAndGetPointerAddress());
for (int i = 0; i < headers.size(); ++i)
{
WinRTWrapper::ScopedHString headerName (headers[i].upToFirstOccurrenceOf (":", false, false).trim());
WinRTWrapper::ScopedHString headerValue (headers[i].fromFirstOccurrenceOf (":", false, false).trim());
headerCollection->Append (headerName.get(), headerValue.get());
}
}
WinRTWrapper::ComPtr<IHttpRequestMessage> createHttpRequestMessage (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
auto requestFactory
= WinRTWrapper::getInstance()->getWRLFactory<IHttpRequestMessageFactory> (RuntimeClass_Windows_Web_Http_HttpRequestMessage);
if (requestFactory == nullptr)
{
jassertfalse;
return {};
}
bool isPOSTRequest = (postData != nullptr && postData->getSize() > 0);
auto method = getMethod (isPOSTRequest);
auto uri = createURI (url);
WinRTWrapper::ComPtr<IHttpRequestMessage> requestMessage;
requestFactory->Create (method.get(), uri.get(), requestMessage.resetAndGetPointerAddress());
if (isPOSTRequest)
{
auto content = getPOSTContent (*postData);
requestMessage->put_Content (content.get());
}
if (headers != nullptr && ! headers->isEmpty())
addHttpHeaders (requestMessage, *headers);
return requestMessage;
}
//==============================================================================
void setControlBounds (Rectangle<int> newBounds) const
{
if (webViewControl != nullptr)
{
#if JUCE_WIN_PER_MONITOR_DPI_AWARE
if (auto* peer = owner.getTopLevelComponent()->getPeer())
newBounds = (newBounds.toDouble() * peer->getPlatformScaleFactor()).toNearestInt();
#endif
WinRTWrapper::ComPtr<IWebViewControlSite> site;
if (SUCCEEDED (webViewControl->QueryInterface (site.resetAndGetPointerAddress())))
site->put_Bounds ({ static_cast<FLOAT> (newBounds.getX()), static_cast<FLOAT> (newBounds.getY()),
static_cast<FLOAT> (newBounds.getWidth()), static_cast<FLOAT> (newBounds.getHeight()) });
}
}
void setControlVisible (bool shouldBeVisible) const
{
if (webViewControl != 0)
{
WinRTWrapper::ComPtr<IWebViewControlSite> site;
if (SUCCEEDED (webViewControl->QueryInterface (site.resetAndGetPointerAddress())))
site->put_IsVisible (shouldBeVisible);
}
}
//==============================================================================
WebBrowserComponent& owner;
WinRTWrapper::ComPtr<IWebViewControlProcess> webViewProcess;
WinRTWrapper::ComPtr<IWebViewControl> webViewControl;
EventRegistrationToken navigationStartingToken { 0 },
newWindowRequestedToken { 0 },
navigationCompletedToken { 0 };
bool isCreating = false;
};
#endif
//==============================================================================
class WebBrowserComponent::Pimpl
{
public:
Pimpl (WebBrowserComponent& owner)
{
#if JUCE_USE_WINRT_WEBVIEW
auto windowsVersionInfo = getWindowsVersionInfo();
if (windowsVersionInfo.dwMajorVersion >= 10 && windowsVersionInfo.dwBuildNumber >= 17763)
{
try
{
internal.reset (new WinRTWebView (owner));
}
catch (std::runtime_error&) {}
}
#endif
if (internal == nullptr)
internal.reset (new Win32WebView (owner));
}
InternalWebViewType& getInternalWebView()
{
return *internal;
}
private:
std::unique_ptr<InternalWebViewType> internal;
};
//==============================================================================
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden)
: browser (new Pimpl (*this)),
unloadPageWhenBrowserIsHidden (unloadWhenHidden)
{
setOpaque (true);
addAndMakeVisible (browser.get());
}
WebBrowserComponent::~WebBrowserComponent()
@ -264,16 +861,15 @@ void WebBrowserComponent::goToURL (const String& url,
blankPageShown = false;
if (browser->browser == nullptr)
if (! browser->getInternalWebView().hasBrowserBeenCreated())
checkWindowAssociation();
browser->goToURL (url, headers, postData);
browser->getInternalWebView().goToURL (url, headers, postData);
}
void WebBrowserComponent::stop()
{
if (browser->browser != nullptr)
browser->browser->Stop();
browser->getInternalWebView().stop();
}
void WebBrowserComponent::goBack()
@ -281,28 +877,25 @@ void WebBrowserComponent::goBack()
lastURL.clear();
blankPageShown = false;
if (browser->browser != nullptr)
browser->browser->GoBack();
browser->getInternalWebView().goBack();
}
void WebBrowserComponent::goForward()
{
lastURL.clear();
if (browser->browser != nullptr)
browser->browser->GoForward();
browser->getInternalWebView().goForward();
}
void WebBrowserComponent::refresh()
{
if (browser->browser != nullptr)
browser->browser->Refresh();
browser->getInternalWebView().refresh();
}
//==============================================================================
void WebBrowserComponent::paint (Graphics& g)
{
if (browser->browser == nullptr)
if (! browser->getInternalWebView().hasBrowserBeenCreated())
{
g.fillAll (Colours::white);
checkWindowAssociation();
@ -313,9 +906,9 @@ void WebBrowserComponent::checkWindowAssociation()
{
if (isShowing())
{
if (browser->browser == nullptr && getPeer() != nullptr)
if (! browser->getInternalWebView().hasBrowserBeenCreated() && getPeer() != nullptr)
{
browser->createBrowser();
browser->getInternalWebView().createBrowser();
reloadLastURL();
}
else
@ -333,7 +926,7 @@ void WebBrowserComponent::checkWindowAssociation()
// page to avoid this..
blankPageShown = true;
browser->goToURL ("about:blank", 0, 0);
browser->getInternalWebView().goToURL ("about:blank", 0, 0);
}
}
}
@ -354,7 +947,7 @@ void WebBrowserComponent::parentHierarchyChanged()
void WebBrowserComponent::resized()
{
browser->setSize (getWidth(), getHeight());
browser->getInternalWebView().setWebViewSize (getWidth(), getHeight());
}
void WebBrowserComponent::visibilityChanged()
@ -364,28 +957,7 @@ void WebBrowserComponent::visibilityChanged()
void WebBrowserComponent::focusGained (FocusChangeType)
{
auto iidOleObject = __uuidof (IOleObject);
auto iidOleWindow = __uuidof (IOleWindow);
if (auto oleObject = (IOleObject*) browser->queryInterface (&iidOleObject))
{
if (auto oleWindow = (IOleWindow*) browser->queryInterface (&iidOleWindow))
{
IOleClientSite* oleClientSite = nullptr;
if (SUCCEEDED (oleObject->GetClientSite (&oleClientSite)))
{
HWND hwnd;
oleWindow->GetWindow (&hwnd);
oleObject->DoVerb (OLEIVERB_UIACTIVATE, nullptr, oleClientSite, 0, hwnd, nullptr);
oleClientSite->Release();
}
oleWindow->Release();
}
oleObject->Release();
}
browser->getInternalWebView().focusGained();
}
void WebBrowserComponent::clearCookies()