diff --git a/modules/juce_audio_devices/juce_audio_devices.h b/modules/juce_audio_devices/juce_audio_devices.h index 30eac198c7..a11b1e7eba 100644 --- a/modules/juce_audio_devices/juce_audio_devices.h +++ b/modules/juce_audio_devices/juce_audio_devices.h @@ -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 diff --git a/modules/juce_events/juce_events.cpp b/modules/juce_events/juce_events.cpp index 29e4442f40..ab3470594f 100644 --- a/modules/juce_events/juce_events.cpp +++ b/modules/juce_events/juce_events.cpp @@ -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 diff --git a/modules/juce_events/juce_events.h b/modules/juce_events/juce_events.h index a91135bb46..7bb0da2a63 100644 --- a/modules/juce_events/juce_events.h +++ b/modules/juce_events/juce_events.h @@ -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 diff --git a/modules/juce_events/native/juce_win32_WinRTWrapper.h b/modules/juce_events/native/juce_win32_WinRTWrapper.h index db25d933a8..945531b1fe 100644 --- a/modules/juce_events/native/juce_win32_WinRTWrapper.h +++ b/modules/juce_events/native/juce_win32_WinRTWrapper.h @@ -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; } diff --git a/modules/juce_gui_extra/juce_gui_extra.cpp b/modules/juce_gui_extra/juce_gui_extra.cpp index edeeeed860..d043e4542f 100644 --- a/modules/juce_gui_extra/juce_gui_extra.cpp +++ b/modules/juce_gui_extra/juce_gui_extra.cpp @@ -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 #include + #if JUCE_USE_WINRT_WEBVIEW + #include + #include + #include + #include + + #pragma warning (push) + #pragma warning (disable: 4265) + #include + #include + #pragma warning (pop) + #endif #endif //============================================================================== diff --git a/modules/juce_gui_extra/juce_gui_extra.h b/modules/juce_gui_extra/juce_gui_extra.h index 75e3a98314..db475d98c0 100644 --- a/modules/juce_gui_extra/juce_gui_extra.h +++ b/modules/juce_gui_extra/juce_gui_extra.h @@ -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 diff --git a/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp b/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp index f1528cefef..5a5c55d9a3 100644 --- a/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp +++ b/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp @@ -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 (getParentComponent()); + auto* owner = dynamic_cast (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 + static HRESULT waitForCompletion (IAsyncOperation* op, ResultsType* results) + { + using OperationType = IAsyncOperation; + using DelegateType = IAsyncOperationCompletedHandler; + + struct EventDelegate : public RuntimeClass, + 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 operation = op; + WinRTWrapper::ComPtr eventCallback; + + auto hr = MakeAndInitialize (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 asyncInfo; + + if (SUCCEEDED (operation->QueryInterface (asyncInfo.resetAndGetPointerAddress()))) + asyncInfo->get_ErrorCode (&hr); + } + } + } + } + + return hr; + } + + //============================================================================== + template + String getURIStringFromArgs (ArgsType& args) + { + WinRTWrapper::ComPtr 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> ( + [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> ( + [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> ( + [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 (RuntimeClass_Windows_Web_UI_Interop_WebViewControlProcess); + + if (webViewControlProcessFactory == nullptr) + { + jassertfalse; + return false; + } + + auto webViewProcessOptions + = WinRTWrapper::getInstance()->activateInstance (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 svs (isCreating, true); + + WinRTWrapper::ComPtr> createWebViewAsyncOperation; + + webViewProcess->CreateWebViewControlAsync ((INT64) peer->getNativeHandle(), {}, + createWebViewAsyncOperation.resetAndGetPointerAddress()); + + waitForCompletion (createWebViewAsyncOperation.get(), webViewControl.resetAndGetPointerAddress()); + + addEventHandlers(); + componentMovedOrResized (true, true); + } + } + + //============================================================================== + WinRTWrapper::ComPtr createURI (const String& url) + { + auto uriRuntimeFactory + = WinRTWrapper::getInstance()->getWRLFactory (RuntimeClass_Windows_Foundation_Uri); + + if (uriRuntimeFactory == nullptr) + { + jassertfalse; + return {}; + } + + WinRTWrapper::ScopedHString hstr (url); + WinRTWrapper::ComPtr uriRuntimeClass; + uriRuntimeFactory->CreateUri (hstr.get(), uriRuntimeClass.resetAndGetPointerAddress()); + + return uriRuntimeClass; + } + + WinRTWrapper::ComPtr getPOSTContent (const MemoryBlock& postData) + { + auto factory = WinRTWrapper::getInstance()->getWRLFactory (RuntimeClass_Windows_Web_Http_HttpStringContent); + + if (factory == nullptr) + { + jassertfalse; + return {}; + } + + WinRTWrapper::ScopedHString hStr (postData.toString()); + + WinRTWrapper::ComPtr content; + factory->CreateFromString (hStr.get(), content.resetAndGetPointerAddress()); + + return content; + } + + WinRTWrapper::ComPtr getMethod (bool isPOST) + { + auto methodFactory = WinRTWrapper::getInstance()->getWRLFactory (RuntimeClass_Windows_Web_Http_HttpMethod); + + if (methodFactory == nullptr) + { + jassertfalse; + return {}; + } + + WinRTWrapper::ComPtr method; + + if (isPOST) + methodFactory->get_Post (method.resetAndGetPointerAddress()); + else + methodFactory->get_Get (method.resetAndGetPointerAddress()); + + return method; + } + + void addHttpHeaders (WinRTWrapper::ComPtr& requestMessage, const StringArray& headers) + { + WinRTWrapper::ComPtr 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 createHttpRequestMessage (const String& url, + const StringArray* headers, + const MemoryBlock* postData) + { + auto requestFactory + = WinRTWrapper::getInstance()->getWRLFactory (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 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 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 site; + + if (SUCCEEDED (webViewControl->QueryInterface (site.resetAndGetPointerAddress()))) + site->put_Bounds ({ static_cast (newBounds.getX()), static_cast (newBounds.getY()), + static_cast (newBounds.getWidth()), static_cast (newBounds.getHeight()) }); + } + + } + + void setControlVisible (bool shouldBeVisible) const + { + if (webViewControl != 0) + { + WinRTWrapper::ComPtr site; + + if (SUCCEEDED (webViewControl->QueryInterface (site.resetAndGetPointerAddress()))) + site->put_IsVisible (shouldBeVisible); + } + } + + //============================================================================== + WebBrowserComponent& owner; + + WinRTWrapper::ComPtr webViewProcess; + WinRTWrapper::ComPtr 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 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()