Make it possible to compile wxWebView Edge backend with gcc

Remove the requirement to include wrl/event.h so that GNU C++ (maybe
Clang C++ as well) can compile this file without error.
This commit is contained in:
nns52k
2021-01-17 23:35:51 +08:00
committed by Vadim Zeitlin
parent df20e5ec76
commit b465a95dcc

View File

@@ -26,10 +26,87 @@
#include "wx/msw/private/cotaskmemptr.h" #include "wx/msw/private/cotaskmemptr.h"
#include "wx/msw/private/webview_edge.h" #include "wx/msw/private/webview_edge.h"
#include <wrl/event.h> #include <objbase.h>
#include <Objbase.h> #include <atomic>
using namespace Microsoft::WRL; template <typename baseT, typename ...argTs>
class CInvokable : public baseT
{
public:
CInvokable() : m_nRefCount(0) {}
virtual ~CInvokable() {}
// IUnknown methods
HRESULT QueryInterface(REFIID WXUNUSED(riid), void **ppvObj) override
{
/**
* WebView2 Runtime apparently doesn't use this method, so it doesn't
* matter how we implement this. On the other hand, this method must be
* implemented to make this invokable type a concrete class instead of a
* abstract one.
*/
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG AddRef(void) override {
return ++m_nRefCount;
}
ULONG Release(void) override {
size_t ret = --m_nRefCount;
if (ret == 0)
delete this;
return ret;
}
private:
std::atomic<size_t> m_nRefCount;
};
template <typename baseT, typename ...argTs>
class CInvokableLambda : public CInvokable<baseT, argTs...>
{
public:
CInvokableLambda(std::function<HRESULT(argTs...)> lambda)
: m_lambda(lambda) {
}
// baseT method
HRESULT Invoke(argTs ...args) override {
return m_lambda(args...);
}
private:
std::function<HRESULT(argTs...)> m_lambda;
};
template <typename baseT, typename contextT, typename ...argTs>
class CInvokableMethod : public CInvokable<baseT, argTs...>
{
public:
CInvokableMethod(contextT *ctx, HRESULT (contextT::*mthd)(argTs...))
: m_ctx(ctx), m_mthd(mthd) {
}
// baseT method
HRESULT Invoke(argTs ...args) override {
return (m_ctx->*m_mthd)(args...);
}
private:
contextT *m_ctx;
HRESULT (contextT::*m_mthd)(argTs...);
};
// the function templates to generate concrete classes from above class templates
template <
typename baseT, typename lambdaT, // base type & lambda type
typename LT, typename ...argTs // for capturing argument types of lambda
>
baseT *callback_impl(lambdaT&& lambda, HRESULT (LT::*)(argTs...) const)
{
return new CInvokableLambda<baseT, argTs...>(lambda);
}
template <typename baseT, typename lambdaT>
baseT *callback(lambdaT&& lambda)
{
return callback_impl<baseT>(std::move(lambda), &lambdaT::operator());
}
template <typename baseT, typename contextT, typename ...argTs>
baseT *callback(contextT *ctx, HRESULT (contextT::*mthd)(argTs...))
{
return new CInvokableMethod<baseT, contextT, argTs...>(ctx, mthd);
}
wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEdge, wxWebView); wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEdge, wxWebView);
@@ -93,8 +170,8 @@ bool wxWebViewEdgeImpl::Create()
ms_browserExecutableDir.wc_str(), ms_browserExecutableDir.wc_str(),
userDataPath.wc_str(), userDataPath.wc_str(),
nullptr, nullptr,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this, callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
&wxWebViewEdgeImpl::OnEnvironmentCreated).Get()); &wxWebViewEdgeImpl::OnEnvironmentCreated));
if (FAILED(hr)) if (FAILED(hr))
{ {
wxLogApiError("CreateWebView2EnvironmentWithOptions", hr); wxLogApiError("CreateWebView2EnvironmentWithOptions", hr);
@@ -110,8 +187,8 @@ HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated(
environment->QueryInterface(IID_PPV_ARGS(&m_webViewEnvironment)); environment->QueryInterface(IID_PPV_ARGS(&m_webViewEnvironment));
m_webViewEnvironment->CreateCoreWebView2Controller( m_webViewEnvironment->CreateCoreWebView2Controller(
m_ctrl->GetHWND(), m_ctrl->GetHWND(),
Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>( callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
this, &wxWebViewEdgeImpl::OnWebViewCreated).Get()); this, &wxWebViewEdgeImpl::OnWebViewCreated));
return S_OK; return S_OK;
} }
@@ -241,8 +318,8 @@ HRESULT wxWebViewEdgeImpl::OnNavigationCompleted(ICoreWebView2* WXUNUSED(sender)
} }
else else
{ {
if (m_historyEnabled && !m_historyLoadingFromList && if ((m_historyEnabled && !m_historyLoadingFromList &&
(uri == m_ctrl->GetCurrentURL()) || (uri == m_ctrl->GetCurrentURL())) ||
(m_ctrl->GetCurrentURL().substr(0, 4) == "file" && (m_ctrl->GetCurrentURL().substr(0, 4) == "file" &&
wxFileName::URLToFileName(m_ctrl->GetCurrentURL()).GetFullPath() == uri)) wxFileName::URLToFileName(m_ctrl->GetCurrentURL()).GetFullPath() == uri))
{ {
@@ -340,28 +417,28 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
// Connect and handle the various WebView events // Connect and handle the various WebView events
m_webView->add_NavigationStarting( m_webView->add_NavigationStarting(
Callback<ICoreWebView2NavigationStartingEventHandler>( callback<ICoreWebView2NavigationStartingEventHandler>(
this, &wxWebViewEdgeImpl::OnNavigationStarting).Get(), this, &wxWebViewEdgeImpl::OnNavigationStarting),
&m_navigationStartingToken); &m_navigationStartingToken);
m_webView->add_SourceChanged( m_webView->add_SourceChanged(
Callback<ICoreWebView2SourceChangedEventHandler>( Callback<ICoreWebView2SourceChangedEventHandler>(
this, &wxWebViewEdgeImpl::OnSourceChanged).Get(), this, &wxWebViewEdgeImpl::OnSourceChanged).Get(),
&m_sourceChangedToken); &m_sourceChangedToken);
m_webView->add_NavigationCompleted( m_webView->add_NavigationCompleted(
Callback<ICoreWebView2NavigationCompletedEventHandler>( callback<ICoreWebView2NavigationCompletedEventHandler>(
this, &wxWebViewEdgeImpl::OnNavigationCompleted).Get(), this, &wxWebViewEdgeImpl::OnNavigationCompleted),
&m_navigationCompletedToken); &m_navigationCompletedToken);
m_webView->add_NewWindowRequested( m_webView->add_NewWindowRequested(
Callback<ICoreWebView2NewWindowRequestedEventHandler>( callback<ICoreWebView2NewWindowRequestedEventHandler>(
this, &wxWebViewEdgeImpl::OnNewWindowRequested).Get(), this, &wxWebViewEdgeImpl::OnNewWindowRequested),
&m_newWindowRequestedToken); &m_newWindowRequestedToken);
m_webView->add_DocumentTitleChanged( m_webView->add_DocumentTitleChanged(
Callback<ICoreWebView2DocumentTitleChangedEventHandler>( callback<ICoreWebView2DocumentTitleChangedEventHandler>(
this, &wxWebViewEdgeImpl::OnDocumentTitleChanged).Get(), this, &wxWebViewEdgeImpl::OnDocumentTitleChanged),
&m_documentTitleChangedToken); &m_documentTitleChangedToken);
m_webView->add_ContentLoading( m_webView->add_ContentLoading(
Callback<ICoreWebView2ContentLoadingEventHandler>( callback<ICoreWebView2ContentLoadingEventHandler>(
this, &wxWebViewEdgeImpl::OnContentLoading).Get(), this, &wxWebViewEdgeImpl::OnContentLoading),
&m_contentLoadingToken); &m_contentLoadingToken);
m_webView->add_ContainsFullScreenElementChanged( m_webView->add_ContainsFullScreenElementChanged(
Callback<ICoreWebView2ContainsFullScreenElementChangedEventHandler>( Callback<ICoreWebView2ContainsFullScreenElementChangedEventHandler>(
@@ -709,7 +786,7 @@ bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output)
bool scriptExecuted = false; bool scriptExecuted = false;
// Start script execution // Start script execution
HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), Callback<ICoreWebView2ExecuteScriptCompletedHandler>( HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), callback<ICoreWebView2ExecuteScriptCompletedHandler>(
[&scriptExecuted, &executionResult, output](HRESULT error, PCWSTR result) -> HRESULT [&scriptExecuted, &executionResult, output](HRESULT error, PCWSTR result) -> HRESULT
{ {
// Handle script execution callback // Handle script execution callback
@@ -724,7 +801,7 @@ bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output)
scriptExecuted = true; scriptExecuted = true;
return S_OK; return S_OK;
}).Get()); }));
// Wait for script exection // Wait for script exection
while (!scriptExecuted) while (!scriptExecuted)
@@ -772,7 +849,7 @@ bool wxWebViewEdge::RunScript(const wxString& javascript, wxString* output) cons
return true; return true;
} }
void wxWebViewEdge::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) void wxWebViewEdge::RegisterHandler(wxSharedPtr<wxWebViewHandler> WXUNUSED(handler))
{ {
// TODO: could maybe be implemented via IWebView2WebView5::add_WebResourceRequested // TODO: could maybe be implemented via IWebView2WebView5::add_WebResourceRequested
wxLogDebug("Registering handlers is not supported"); wxLogDebug("Registering handlers is not supported");