| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE 6 technical preview.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    You may use this code under the terms of the GPL v3
 -    (see www.gnu.org/licenses).
 - 
 -    For this technical preview, this file is not subject to commercial licensing.
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - 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")
 - 
 -  #ifndef WebBrowser
 -   class WebBrowser;
 -  #endif
 - #endif
 - 
 - JUCE_DECLARE_UUID_GETTER (DWebBrowserEvents2,        "34A715A0-6587-11D0-924A-0020AFC7AC4D")
 - JUCE_DECLARE_UUID_GETTER (IConnectionPointContainer, "B196B284-BAB4-101A-B69C-00AA00341D07")
 - JUCE_DECLARE_UUID_GETTER (IWebBrowser2,              "D30C1661-CDAF-11D0-8A3E-00C04FC9E26E")
 - JUCE_DECLARE_UUID_GETTER (WebBrowser,                "8856F961-340A-11D0-A96B-00C04FD705A2")
 - 
 - //==============================================================================
 - class Win32WebView   : public InternalWebViewType,
 -                        public ActiveXControlComponent
 - {
 - public:
 -     Win32WebView (WebBrowserComponent& owner)
 -     {
 -         owner.addAndMakeVisible (this);
 -     }
 - 
 -     ~Win32WebView() override
 -     {
 -         if (connectionPoint != nullptr)
 -             connectionPoint->Unadvise (adviseCookie);
 - 
 -         if (browser != nullptr)
 -             browser->Release();
 -     }
 - 
 -     void createBrowser() override
 -     {
 -         auto webCLSID = __uuidof (WebBrowser);
 -         createControl (&webCLSID);
 - 
 -         auto iidWebBrowser2              = __uuidof (IWebBrowser2);
 -         auto iidConnectionPointContainer = __uuidof (IConnectionPointContainer);
 - 
 -         browser = (IWebBrowser2*) queryInterface (&iidWebBrowser2);
 - 
 -         if (auto connectionPointContainer = (IConnectionPointContainer*) queryInterface (&iidConnectionPointContainer))
 -         {
 -             connectionPointContainer->FindConnectionPoint (__uuidof (DWebBrowserEvents2), &connectionPoint);
 - 
 -             if (connectionPoint != nullptr)
 -             {
 -                 auto* owner = dynamic_cast<WebBrowserComponent*> (Component::getParentComponent());
 -                 jassert (owner != nullptr);
 - 
 -                 auto handler = new EventHandler (*owner);
 -                 connectionPoint->Advise (handler, &adviseCookie);
 -                 handler->Release();
 -             }
 -         }
 -     }
 - 
 -     bool hasBrowserBeenCreated() override
 -     {
 -         return browser != nullptr;
 -     }
 - 
 -     void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) override
 -     {
 -         if (browser != nullptr)
 -         {
 -             VARIANT headerFlags, frame, postDataVar, headersVar;  // (_variant_t isn't available in all compilers)
 -             VariantInit (&headerFlags);
 -             VariantInit (&frame);
 -             VariantInit (&postDataVar);
 -             VariantInit (&headersVar);
 - 
 -             if (headers != nullptr)
 -             {
 -                 V_VT (&headersVar) = VT_BSTR;
 -                 V_BSTR (&headersVar) = SysAllocString ((const OLECHAR*) headers->joinIntoString ("\r\n").toWideCharPointer());
 -             }
 - 
 -             if (postData != nullptr && postData->getSize() > 0)
 -             {
 -                 auto sa = SafeArrayCreateVector (VT_UI1, 0, (ULONG) postData->getSize());
 - 
 -                 if (sa != nullptr)
 -                 {
 -                     void* data = nullptr;
 -                     SafeArrayAccessData (sa, &data);
 -                     jassert (data != nullptr);
 - 
 -                     if (data != nullptr)
 -                     {
 -                         postData->copyTo (data, 0, postData->getSize());
 -                         SafeArrayUnaccessData (sa);
 - 
 -                         VARIANT postDataVar2;
 -                         VariantInit (&postDataVar2);
 -                         V_VT (&postDataVar2) = VT_ARRAY | VT_UI1;
 -                         V_ARRAY (&postDataVar2) = sa;
 - 
 -                         sa = nullptr;
 -                         postDataVar = postDataVar2;
 -                     }
 -                     else
 -                     {
 -                         SafeArrayDestroy (sa);
 -                     }
 -                 }
 -             }
 - 
 -             auto urlBSTR = SysAllocString ((const OLECHAR*) url.toWideCharPointer());
 -             browser->Navigate (urlBSTR, &headerFlags, &frame, &postDataVar, &headersVar);
 -             SysFreeString (urlBSTR);
 - 
 -             VariantClear (&headerFlags);
 -             VariantClear (&frame);
 -             VariantClear (&postDataVar);
 -             VariantClear (&headersVar);
 -         }
 -     }
 - 
 -     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;
 - 
 -     //==============================================================================
 -     struct EventHandler  : public ComBaseClassHelper<IDispatch>,
 -                            public ComponentMovementWatcher
 -     {
 -         EventHandler (WebBrowserComponent& w)  : ComponentMovementWatcher (&w), owner (w) {}
 - 
 -         JUCE_COMRESULT GetTypeInfoCount (UINT*) override                                 { return E_NOTIMPL; }
 -         JUCE_COMRESULT GetTypeInfo (UINT, LCID, ITypeInfo**) override                    { return E_NOTIMPL; }
 -         JUCE_COMRESULT GetIDsOfNames (REFIID, LPOLESTR*, UINT, LCID, DISPID*) override   { return E_NOTIMPL; }
 - 
 -         JUCE_COMRESULT Invoke (DISPID dispIdMember, REFIID /*riid*/, LCID /*lcid*/, WORD /*wFlags*/, DISPPARAMS* pDispParams,
 -                                VARIANT* /*pVarResult*/, EXCEPINFO* /*pExcepInfo*/, UINT* /*puArgErr*/) override
 -         {
 -             if (dispIdMember == DISPID_BEFORENAVIGATE2)
 -             {
 -                 *pDispParams->rgvarg->pboolVal
 -                     = owner.pageAboutToLoad (getStringFromVariant (pDispParams->rgvarg[5].pvarVal)) ? VARIANT_FALSE
 -                                                                                                     : VARIANT_TRUE;
 -                 return S_OK;
 -             }
 - 
 -             if (dispIdMember == 273 /*DISPID_NEWWINDOW3*/)
 -             {
 -                 owner.newWindowAttemptingToLoad (pDispParams->rgvarg[0].bstrVal);
 -                 *pDispParams->rgvarg[3].pboolVal = VARIANT_TRUE;
 -                 return S_OK;
 -             }
 - 
 -             if (dispIdMember == DISPID_DOCUMENTCOMPLETE)
 -             {
 -                 owner.pageFinishedLoading (getStringFromVariant (pDispParams->rgvarg[0].pvarVal));
 -                 return S_OK;
 -             }
 - 
 -             if (dispIdMember == 271 /*DISPID_NAVIGATEERROR*/)
 -             {
 -                 int statusCode = pDispParams->rgvarg[1].pvarVal->intVal;
 -                 *pDispParams->rgvarg[0].pboolVal = VARIANT_FALSE;
 - 
 -                 // IWebBrowser2 also reports http status codes here, we need
 -                 // report only network errors
 -                 if (statusCode < 0)
 -                 {
 -                     LPTSTR messageBuffer = nullptr;
 -                     auto size = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
 -                                                nullptr, statusCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 -                                                (LPTSTR) &messageBuffer, 0, nullptr);
 - 
 -                     String message (messageBuffer, size);
 -                     LocalFree (messageBuffer);
 - 
 -                     if (! owner.pageLoadHadNetworkError (message))
 -                         *pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE;
 -                 }
 - 
 -                 return S_OK;
 -             }
 - 
 -             if (dispIdMember == 263 /*DISPID_WINDOWCLOSING*/)
 -             {
 -                 owner.windowCloseRequest();
 - 
 -                 // setting this bool tells the browser to ignore the event - we'll handle it.
 -                 if (pDispParams->cArgs > 0 && pDispParams->rgvarg[0].vt == (VT_BYREF | VT_BOOL))
 -                     *pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE;
 - 
 -                 return S_OK;
 -             }
 - 
 -             return E_NOTIMPL;
 -         }
 - 
 -         void componentMovedOrResized (bool, bool) override   {}
 -         void componentPeerChanged() override                 {}
 -         void componentVisibilityChanged() override           { owner.visibilityChanged(); }
 - 
 -     private:
 -         WebBrowserComponent& owner;
 - 
 -         static String getStringFromVariant (VARIANT* v)
 -         {
 -             return (v->vt & VT_BYREF) != 0 ? *v->pbstrVal
 -                                            : v->bstrVal;
 -         }
 - 
 -         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EventHandler)
 -     };
 - };
 - 
 - #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;
 - 
 - //==============================================================================
 - 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);
 - }
 - 
 - WebBrowserComponent::~WebBrowserComponent()
 - {
 - }
 - 
 - //==============================================================================
 - void WebBrowserComponent::goToURL (const String& url,
 -                                    const StringArray* headers,
 -                                    const MemoryBlock* postData)
 - {
 -     lastURL = url;
 - 
 -     if (headers != nullptr)
 -         lastHeaders = *headers;
 -     else
 -         lastHeaders.clear();
 - 
 -     if (postData != nullptr)
 -         lastPostData = *postData;
 -     else
 -         lastPostData.reset();
 - 
 -     blankPageShown = false;
 - 
 -     if (! browser->getInternalWebView().hasBrowserBeenCreated())
 -         checkWindowAssociation();
 - 
 -     browser->getInternalWebView().goToURL (url, headers, postData);
 - }
 - 
 - void WebBrowserComponent::stop()
 - {
 -     browser->getInternalWebView().stop();
 - }
 - 
 - void WebBrowserComponent::goBack()
 - {
 -     lastURL.clear();
 -     blankPageShown = false;
 - 
 -     browser->getInternalWebView().goBack();
 - }
 - 
 - void WebBrowserComponent::goForward()
 - {
 -     lastURL.clear();
 - 
 -     browser->getInternalWebView().goForward();
 - }
 - 
 - void WebBrowserComponent::refresh()
 - {
 -     browser->getInternalWebView().refresh();
 - }
 - 
 - //==============================================================================
 - void WebBrowserComponent::paint (Graphics& g)
 - {
 -     if (! browser->getInternalWebView().hasBrowserBeenCreated())
 -     {
 -         g.fillAll (Colours::white);
 -         checkWindowAssociation();
 -     }
 - }
 - 
 - void WebBrowserComponent::checkWindowAssociation()
 - {
 -     if (isShowing())
 -     {
 -         if (! browser->getInternalWebView().hasBrowserBeenCreated() && getPeer() != nullptr)
 -         {
 -             browser->getInternalWebView().createBrowser();
 -             reloadLastURL();
 -         }
 -         else
 -         {
 -             if (blankPageShown)
 -                 goBack();
 -         }
 -     }
 -     else
 -     {
 -         if (browser != nullptr && unloadPageWhenBrowserIsHidden && ! blankPageShown)
 -         {
 -             // when the component becomes invisible, some stuff like flash
 -             // carries on playing audio, so we need to force it onto a blank
 -             // page to avoid this..
 - 
 -             blankPageShown = true;
 -             browser->getInternalWebView().goToURL ("about:blank", 0, 0);
 -         }
 -     }
 - }
 - 
 - void WebBrowserComponent::reloadLastURL()
 - {
 -     if (lastURL.isNotEmpty())
 -     {
 -         goToURL (lastURL, &lastHeaders, &lastPostData);
 -         lastURL.clear();
 -     }
 - }
 - 
 - void WebBrowserComponent::parentHierarchyChanged()
 - {
 -     checkWindowAssociation();
 - }
 - 
 - void WebBrowserComponent::resized()
 - {
 -     browser->getInternalWebView().setWebViewSize (getWidth(), getHeight());
 - }
 - 
 - void WebBrowserComponent::visibilityChanged()
 - {
 -     checkWindowAssociation();
 - }
 - 
 - void WebBrowserComponent::focusGained (FocusChangeType)
 - {
 -     browser->getInternalWebView().focusGained();
 - }
 - 
 - void WebBrowserComponent::clearCookies()
 - {
 -     HeapBlock<::INTERNET_CACHE_ENTRY_INFOA> entry;
 -     ::DWORD entrySize = sizeof (::INTERNET_CACHE_ENTRY_INFOA);
 -     ::HANDLE urlCacheHandle = ::FindFirstUrlCacheEntryA ("cookie:", entry.getData(), &entrySize);
 - 
 -     if (urlCacheHandle == nullptr && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
 -     {
 -         entry.realloc (1, entrySize);
 -         urlCacheHandle = ::FindFirstUrlCacheEntryA ("cookie:", entry.getData(), &entrySize);
 -     }
 - 
 -     if (urlCacheHandle != nullptr)
 -     {
 -         for (;;)
 -         {
 -             ::DeleteUrlCacheEntryA (entry.getData()->lpszSourceUrlName);
 - 
 -             if (::FindNextUrlCacheEntryA (urlCacheHandle, entry.getData(), &entrySize) == 0)
 -             {
 -                 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
 -                 {
 -                     entry.realloc (1, entrySize);
 - 
 -                     if (::FindNextUrlCacheEntryA (urlCacheHandle, entry.getData(), &entrySize) != 0)
 -                         continue;
 -                 }
 - 
 -                 break;
 -             }
 -         }
 - 
 -         FindCloseUrlCache (urlCacheHandle);
 -     }
 - }
 - 
 - } // namespace juce
 
 
  |