Move project to use latest WebView2 SDK 0.9.430 (#8)
* Update WebView2 sdk to 0.9.430
* Revert "Add arm64 config"
This reverts commit 7f16c08153
.
* Update minimum browser version
* Rename m_contentReceiver to m_securityStateChangedReceiver
This commit is contained in:
Родитель
1a27038ddd
Коммит
9501cf6f2d
|
@ -186,9 +186,9 @@ BOOL BrowserWindow::InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|||
// tabs will be created from this environment and kept isolated from the
|
||||
// browser UI. This enviroment is created first so the UI can request new
|
||||
// tabs when it's ready.
|
||||
HRESULT hr = CreateWebView2EnvironmentWithDetails(nullptr, userDataDirectory.c_str(),
|
||||
L"", Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2Environment* env) -> HRESULT
|
||||
HRESULT hr = CreateCoreWebView2EnvironmentWithDetails(nullptr, userDataDirectory.c_str(),
|
||||
L"", Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT
|
||||
{
|
||||
RETURN_IF_FAILED(result);
|
||||
|
||||
|
@ -220,9 +220,9 @@ HRESULT BrowserWindow::InitUIWebViews()
|
|||
|
||||
// Create WebView environment for browser UI. A separate data directory is
|
||||
// used to isolate the browser UI from web content requested by the user.
|
||||
return CreateWebView2EnvironmentWithDetails(nullptr, browserDataDirectory.c_str(),
|
||||
L"", Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2Environment* env) -> HRESULT
|
||||
return CreateCoreWebView2EnvironmentWithDetails(nullptr, browserDataDirectory.c_str(),
|
||||
L"", Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT
|
||||
{
|
||||
// Environment is ready, create the WebView
|
||||
m_uiEnv = env;
|
||||
|
@ -236,8 +236,8 @@ HRESULT BrowserWindow::InitUIWebViews()
|
|||
|
||||
HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
||||
{
|
||||
return m_uiEnv->CreateWebView(m_hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2WebView* webview) -> HRESULT
|
||||
return m_uiEnv->CreateCoreWebView2Host(m_hWnd, Callback<ICoreWebView2CreateCoreWebView2HostCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Host* host) -> HRESULT
|
||||
{
|
||||
if (!SUCCEEDED(result))
|
||||
{
|
||||
|
@ -245,17 +245,17 @@ HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
|||
return result;
|
||||
}
|
||||
// WebView created
|
||||
m_controlsWebView = webview;
|
||||
m_controlsHost = host;
|
||||
CheckFailure(m_controlsHost->get_CoreWebView2(&m_controlsWebView), L"");
|
||||
|
||||
wil::com_ptr<IWebView2Settings> settings;
|
||||
wil::com_ptr<ICoreWebView2Settings> settings;
|
||||
RETURN_IF_FAILED(m_controlsWebView->get_Settings(&settings));
|
||||
RETURN_IF_FAILED(settings->put_AreDevToolsEnabled(FALSE));
|
||||
RETURN_IF_FAILED(settings->put_IsFullscreenAllowed(FALSE));
|
||||
|
||||
RETURN_IF_FAILED(m_controlsWebView->add_ZoomFactorChanged(Callback<IWebView2ZoomFactorChangedEventHandler>(
|
||||
[](IWebView2WebView* webview, IUnknown* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_controlsHost->add_ZoomFactorChanged(Callback<ICoreWebView2ZoomFactorChangedEventHandler>(
|
||||
[](ICoreWebView2Host* host, IUnknown* args) -> HRESULT
|
||||
{
|
||||
webview->put_ZoomFactor(1.0);
|
||||
host->put_ZoomFactor(1.0);
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), &m_controlsZoomToken));
|
||||
|
@ -272,8 +272,8 @@ HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
|||
|
||||
HRESULT BrowserWindow::CreateBrowserOptionsWebView()
|
||||
{
|
||||
return m_uiEnv->CreateWebView(m_hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2WebView* webview) -> HRESULT
|
||||
return m_uiEnv->CreateCoreWebView2Host(m_hWnd, Callback<ICoreWebView2CreateCoreWebView2HostCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Host* host) -> HRESULT
|
||||
{
|
||||
if (!SUCCEEDED(result))
|
||||
{
|
||||
|
@ -281,28 +281,28 @@ HRESULT BrowserWindow::CreateBrowserOptionsWebView()
|
|||
return result;
|
||||
}
|
||||
// WebView created
|
||||
m_optionsWebView = webview;
|
||||
m_optionsHost = host;
|
||||
CheckFailure(m_optionsHost->get_CoreWebView2(&m_optionsWebView), L"");
|
||||
|
||||
wil::com_ptr<IWebView2Settings> settings;
|
||||
wil::com_ptr<ICoreWebView2Settings> settings;
|
||||
RETURN_IF_FAILED(m_optionsWebView->get_Settings(&settings));
|
||||
RETURN_IF_FAILED(settings->put_AreDevToolsEnabled(FALSE));
|
||||
RETURN_IF_FAILED(settings->put_IsFullscreenAllowed(FALSE));
|
||||
|
||||
RETURN_IF_FAILED(m_optionsWebView->add_ZoomFactorChanged(Callback<IWebView2ZoomFactorChangedEventHandler>(
|
||||
[](IWebView2WebView* webview, IUnknown* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_optionsHost->add_ZoomFactorChanged(Callback<ICoreWebView2ZoomFactorChangedEventHandler>(
|
||||
[](ICoreWebView2Host* host, IUnknown* args) -> HRESULT
|
||||
{
|
||||
webview->put_ZoomFactor(1.0);
|
||||
host->put_ZoomFactor(1.0);
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), &m_optionsZoomToken));
|
||||
|
||||
// Hide by default
|
||||
RETURN_IF_FAILED(m_optionsWebView->put_IsVisible(FALSE));
|
||||
RETURN_IF_FAILED(m_optionsHost->put_IsVisible(FALSE));
|
||||
RETURN_IF_FAILED(m_optionsWebView->add_WebMessageReceived(m_uiMessageBroker.Get(), &m_optionsUIMessageBrokerToken));
|
||||
|
||||
// Hide menu when focus is lost
|
||||
RETURN_IF_FAILED(m_optionsWebView->add_LostFocus(Callback<IWebView2FocusChangedEventHandler>(
|
||||
[this](IWebView2WebView* sender, IUnknown* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_optionsHost->add_LostFocus(Callback<ICoreWebView2FocusChangedEventHandler>(
|
||||
[this](ICoreWebView2Host* sender, IUnknown* args) -> HRESULT
|
||||
{
|
||||
web::json::value jsonObj = web::json::value::parse(L"{}");
|
||||
jsonObj[L"message"] = web::json::value(MG_OPTIONS_LOST_FOCUS);
|
||||
|
@ -326,8 +326,8 @@ HRESULT BrowserWindow::CreateBrowserOptionsWebView()
|
|||
// Lambda is used to capture the instance while satisfying Microsoft::WRL::Callback<T>()
|
||||
void BrowserWindow::SetUIMessageBroker()
|
||||
{
|
||||
m_uiMessageBroker = Callback<IWebView2WebMessageReceivedEventHandler>(
|
||||
[this](IWebView2WebView* webview, IWebView2WebMessageReceivedEventArgs* eventArgs) -> HRESULT
|
||||
m_uiMessageBroker = Callback<ICoreWebView2WebMessageReceivedEventHandler>(
|
||||
[this](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* eventArgs) -> HRESULT
|
||||
{
|
||||
wil::unique_cotaskmem_string jsonString;
|
||||
CheckFailure(eventArgs->get_WebMessageAsJson(&jsonString), L""); // Get the message from the UI WebView as JSON formatted string
|
||||
|
@ -363,7 +363,7 @@ void BrowserWindow::SetUIMessageBroker()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_tabs.at(id)->m_contentWebView->Close();
|
||||
m_tabs.at(id)->m_contentHost->Close();
|
||||
it->second = std::move(newTab);
|
||||
}
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ void BrowserWindow::SetUIMessageBroker()
|
|||
case MG_CLOSE_TAB:
|
||||
{
|
||||
size_t id = args.at(L"tabId").as_number().to_uint32();
|
||||
m_tabs.at(id)->m_contentWebView->Close();
|
||||
m_tabs.at(id)->m_contentHost->Close();
|
||||
m_tabs.erase(id);
|
||||
}
|
||||
break;
|
||||
|
@ -439,18 +439,18 @@ void BrowserWindow::SetUIMessageBroker()
|
|||
break;
|
||||
case MG_SHOW_OPTIONS:
|
||||
{
|
||||
CheckFailure(m_optionsWebView->put_IsVisible(TRUE), L"");
|
||||
m_optionsWebView->MoveFocus(WEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
|
||||
CheckFailure(m_optionsHost->put_IsVisible(TRUE), L"");
|
||||
m_optionsHost->MoveFocus(CORE_WEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
|
||||
}
|
||||
break;
|
||||
case MG_HIDE_OPTIONS:
|
||||
{
|
||||
CheckFailure(m_optionsWebView->put_IsVisible(FALSE), L"Something went wrong when trying to close the options dropdown.");
|
||||
CheckFailure(m_optionsHost->put_IsVisible(FALSE), L"Something went wrong when trying to close the options dropdown.");
|
||||
}
|
||||
break;
|
||||
case MG_OPTION_SELECTED:
|
||||
{
|
||||
m_tabs.at(m_activeTabId)->m_contentWebView->MoveFocus(WEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
|
||||
m_tabs.at(m_activeTabId)->m_contentHost->MoveFocus(CORE_WEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
|
||||
}
|
||||
break;
|
||||
case MG_GET_FAVORITES:
|
||||
|
@ -480,18 +480,18 @@ HRESULT BrowserWindow::SwitchToTab(size_t tabId)
|
|||
size_t previousActiveTab = m_activeTabId;
|
||||
|
||||
RETURN_IF_FAILED(m_tabs.at(tabId)->ResizeWebView());
|
||||
RETURN_IF_FAILED(m_tabs.at(tabId)->m_contentWebView->put_IsVisible(TRUE));
|
||||
RETURN_IF_FAILED(m_tabs.at(tabId)->m_contentHost->put_IsVisible(TRUE));
|
||||
m_activeTabId = tabId;
|
||||
|
||||
if (previousActiveTab != INVALID_TAB_ID && previousActiveTab != m_activeTabId)
|
||||
{
|
||||
RETURN_IF_FAILED(m_tabs.at(previousActiveTab)->m_contentWebView->put_IsVisible(FALSE));
|
||||
RETURN_IF_FAILED(m_tabs.at(previousActiveTab)->m_contentHost->put_IsVisible(FALSE));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::HandleTabURIUpdate(size_t tabId, IWebView2WebView* webview)
|
||||
HRESULT BrowserWindow::HandleTabURIUpdate(size_t tabId, ICoreWebView2* webview)
|
||||
{
|
||||
wil::unique_cotaskmem_string source;
|
||||
RETURN_IF_FAILED(webview->get_Source(&source));
|
||||
|
@ -520,6 +520,22 @@ HRESULT BrowserWindow::HandleTabURIUpdate(size_t tabId, IWebView2WebView* webvie
|
|||
jsonObj[L"args"][L"uriToShow"] = web::json::value(L"browser://history");
|
||||
}
|
||||
|
||||
RETURN_IF_FAILED(PostJsonToWebView(jsonObj, m_controlsWebView.Get()));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::HandleTabHistoryUpdate(size_t tabId, ICoreWebView2* webview)
|
||||
{
|
||||
wil::unique_cotaskmem_string source;
|
||||
RETURN_IF_FAILED(webview->get_Source(&source));
|
||||
|
||||
web::json::value jsonObj = web::json::value::parse(L"{}");
|
||||
jsonObj[L"message"] = web::json::value(MG_UPDATE_URI);
|
||||
jsonObj[L"args"] = web::json::value::parse(L"{}");
|
||||
jsonObj[L"args"][L"tabId"] = web::json::value::number(tabId);
|
||||
jsonObj[L"args"][L"uri"] = web::json::value(source.get());
|
||||
|
||||
BOOL canGoForward = FALSE;
|
||||
RETURN_IF_FAILED(webview->get_CanGoForward(&canGoForward));
|
||||
jsonObj[L"args"][L"canGoForward"] = web::json::value::boolean(canGoForward);
|
||||
|
@ -533,7 +549,7 @@ HRESULT BrowserWindow::HandleTabURIUpdate(size_t tabId, IWebView2WebView* webvie
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::HandleTabNavStarting(size_t tabId, IWebView2WebView* webview)
|
||||
HRESULT BrowserWindow::HandleTabNavStarting(size_t tabId, ICoreWebView2* webview)
|
||||
{
|
||||
web::json::value jsonObj = web::json::value::parse(L"{}");
|
||||
jsonObj[L"message"] = web::json::value(MG_NAV_STARTING);
|
||||
|
@ -543,7 +559,7 @@ HRESULT BrowserWindow::HandleTabNavStarting(size_t tabId, IWebView2WebView* webv
|
|||
return PostJsonToWebView(jsonObj, m_controlsWebView.Get());
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::HandleTabNavCompleted(size_t tabId, IWebView2WebView* webview, IWebView2NavigationCompletedEventArgs* args)
|
||||
HRESULT BrowserWindow::HandleTabNavCompleted(size_t tabId, ICoreWebView2* webview, ICoreWebView2NavigationCompletedEventArgs* args)
|
||||
{
|
||||
std::wstring getTitleScript(
|
||||
// Look for a title tag
|
||||
|
@ -602,7 +618,7 @@ HRESULT BrowserWindow::HandleTabNavCompleted(size_t tabId, IWebView2WebView* web
|
|||
L"})();"
|
||||
);
|
||||
|
||||
CheckFailure(webview->ExecuteScript(getTitleScript.c_str(), Callback<IWebView2ExecuteScriptCompletedHandler>(
|
||||
CheckFailure(webview->ExecuteScript(getTitleScript.c_str(), Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
|
||||
[this, tabId](HRESULT error, PCWSTR result) -> HRESULT
|
||||
{
|
||||
RETURN_IF_FAILED(error);
|
||||
|
@ -617,7 +633,7 @@ HRESULT BrowserWindow::HandleTabNavCompleted(size_t tabId, IWebView2WebView* web
|
|||
return S_OK;
|
||||
}).Get()), L"Can't update title.");
|
||||
|
||||
CheckFailure(webview->ExecuteScript(getFaviconURI.c_str(), Callback<IWebView2ExecuteScriptCompletedHandler>(
|
||||
CheckFailure(webview->ExecuteScript(getFaviconURI.c_str(), Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
|
||||
[this, tabId](HRESULT error, PCWSTR result) -> HRESULT
|
||||
{
|
||||
RETURN_IF_FAILED(error);
|
||||
|
@ -646,7 +662,7 @@ HRESULT BrowserWindow::HandleTabNavCompleted(size_t tabId, IWebView2WebView* web
|
|||
return PostJsonToWebView(jsonObj, m_controlsWebView.Get());
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::HandleTabSecurityUpdate(size_t tabId, IWebView2WebView* webview, IWebView2DevToolsProtocolEventReceivedEventArgs* args)
|
||||
HRESULT BrowserWindow::HandleTabSecurityUpdate(size_t tabId, ICoreWebView2* webview, ICoreWebView2DevToolsProtocolEventReceivedEventArgs* args)
|
||||
{
|
||||
wil::unique_cotaskmem_string jsonArgs;
|
||||
RETURN_IF_FAILED(args->get_ParameterObjectAsJson(&jsonArgs));
|
||||
|
@ -669,7 +685,7 @@ void BrowserWindow::HandleTabCreated(size_t tabId, bool shouldBeActive)
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::HandleTabMessageReceived(size_t tabId, IWebView2WebView* webview, IWebView2WebMessageReceivedEventArgs* eventArgs)
|
||||
HRESULT BrowserWindow::HandleTabMessageReceived(size_t tabId, ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* eventArgs)
|
||||
{
|
||||
wil::unique_cotaskmem_string jsonString;
|
||||
RETURN_IF_FAILED(eventArgs->get_WebMessageAsJson(&jsonString));
|
||||
|
@ -808,7 +824,7 @@ HRESULT BrowserWindow::ResizeUIWebViews()
|
|||
bounds.bottom = bounds.top + GetDPIAwareBound(c_uiBarHeight);
|
||||
bounds.bottom += 1;
|
||||
|
||||
RETURN_IF_FAILED(m_controlsWebView->put_Bounds(bounds));
|
||||
RETURN_IF_FAILED(m_controlsHost->put_Bounds(bounds));
|
||||
}
|
||||
|
||||
if (m_optionsWebView != nullptr)
|
||||
|
@ -819,7 +835,7 @@ HRESULT BrowserWindow::ResizeUIWebViews()
|
|||
bounds.bottom = bounds.top + GetDPIAwareBound(c_optionsDropdownHeight);
|
||||
bounds.left = bounds.right - GetDPIAwareBound(c_optionsDropdownWidth);
|
||||
|
||||
RETURN_IF_FAILED(m_optionsWebView->put_Bounds(bounds));
|
||||
RETURN_IF_FAILED(m_optionsHost->put_Bounds(bounds));
|
||||
}
|
||||
|
||||
// Workaround for black controls WebView issue in Windows 7
|
||||
|
@ -922,7 +938,7 @@ std::wstring BrowserWindow::GetFilePathAsURI(std::wstring fullPath)
|
|||
return fileURI;
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::PostJsonToWebView(web::json::value jsonObj, IWebView2WebView* webview)
|
||||
HRESULT BrowserWindow::PostJsonToWebView(web::json::value jsonObj, ICoreWebView2* webview)
|
||||
{
|
||||
utility::stringstream_t stream;
|
||||
jsonObj.serialize(stream);
|
||||
|
|
|
@ -21,12 +21,13 @@ public:
|
|||
static BOOL LaunchWindow(_In_ HINSTANCE hInstance, _In_ int nCmdShow);
|
||||
static std::wstring GetAppDataDirectory();
|
||||
std::wstring GetFullPathFor(LPCWSTR relativePath);
|
||||
HRESULT HandleTabURIUpdate(size_t tabId, IWebView2WebView* webview);
|
||||
HRESULT HandleTabNavStarting(size_t tabId, IWebView2WebView* webview);
|
||||
HRESULT HandleTabNavCompleted(size_t tabId, IWebView2WebView* webview, IWebView2NavigationCompletedEventArgs* args);
|
||||
HRESULT HandleTabSecurityUpdate(size_t tabId, IWebView2WebView* webview, IWebView2DevToolsProtocolEventReceivedEventArgs* args);
|
||||
HRESULT HandleTabURIUpdate(size_t tabId, ICoreWebView2* webview);
|
||||
HRESULT HandleTabHistoryUpdate(size_t tabId, ICoreWebView2* webview);
|
||||
HRESULT HandleTabNavStarting(size_t tabId, ICoreWebView2* webview);
|
||||
HRESULT HandleTabNavCompleted(size_t tabId, ICoreWebView2* webview, ICoreWebView2NavigationCompletedEventArgs* args);
|
||||
HRESULT HandleTabSecurityUpdate(size_t tabId, ICoreWebView2* webview, ICoreWebView2DevToolsProtocolEventReceivedEventArgs* args);
|
||||
void HandleTabCreated(size_t tabId, bool shouldBeActive);
|
||||
HRESULT HandleTabMessageReceived(size_t tabId, IWebView2WebView* webview, IWebView2WebMessageReceivedEventArgs* eventArgs);
|
||||
HRESULT HandleTabMessageReceived(size_t tabId, ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* eventArgs);
|
||||
int GetDPIAwareBound(int bound);
|
||||
static void CheckFailure(HRESULT hr, LPCWSTR errorMessage);
|
||||
protected:
|
||||
|
@ -39,10 +40,12 @@ protected:
|
|||
int m_minWindowWidth = 0;
|
||||
int m_minWindowHeight = 0;
|
||||
|
||||
Microsoft::WRL::ComPtr<IWebView2Environment> m_uiEnv;
|
||||
Microsoft::WRL::ComPtr<IWebView2Environment> m_contentEnv;
|
||||
Microsoft::WRL::ComPtr<IWebView2WebView> m_controlsWebView;
|
||||
Microsoft::WRL::ComPtr<IWebView2WebView> m_optionsWebView;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2Environment> m_uiEnv;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2Environment> m_contentEnv;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2Host> m_controlsHost;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2Host> m_optionsHost;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2> m_controlsWebView;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2> m_optionsWebView;
|
||||
std::map<size_t,std::unique_ptr<Tab>> m_tabs;
|
||||
size_t m_activeTabId = 0;
|
||||
|
||||
|
@ -51,7 +54,7 @@ protected:
|
|||
EventRegistrationToken m_optionsUIMessageBrokerToken = {}; // Token for the UI message handler in options WebView
|
||||
EventRegistrationToken m_optionsZoomToken = {};
|
||||
EventRegistrationToken m_lostOptionsFocus = {}; // Token for the lost focus handler in options WebView
|
||||
Microsoft::WRL::ComPtr<IWebView2WebMessageReceivedEventHandler> m_uiMessageBroker;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebMessageReceivedEventHandler> m_uiMessageBroker;
|
||||
|
||||
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
|
||||
HRESULT InitUIWebViews();
|
||||
|
@ -65,7 +68,7 @@ protected:
|
|||
void SetUIMessageBroker();
|
||||
HRESULT ResizeUIWebViews();
|
||||
void UpdateMinWindowSize();
|
||||
HRESULT PostJsonToWebView(web::json::value jsonObj, IWebView2WebView* webview);
|
||||
HRESULT PostJsonToWebView(web::json::value jsonObj, ICoreWebView2* webview);
|
||||
HRESULT SwitchToTab(size_t tabId);
|
||||
std::wstring GetFilePathAsURI(std::wstring fullPath);
|
||||
};
|
||||
|
|
151
README.md
151
README.md
|
@ -1,17 +1,17 @@
|
|||
# WebView2Browser
|
||||
A web browser built with the [Microsoft Edge WebView2](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2) control.
|
||||
A web browser built with the [Microsoft Edge WebView2](https://docs.microsoft.com/microsoft-edge/hosting/webview2) control.
|
||||
|
||||
![WebView2Browser](https://github.com/MicrosoftEdge/WebView2Browser/raw/master/screenshots/WebView2Browser.png)
|
||||
![WebView2Browser](/screenshots/WebView2Browser.png)
|
||||
|
||||
WebView2Browser is a sample Windows desktop application demonstrating the WebView2 control capabilities. It is built as a Win32 [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) project and makes use of both C++ and JavaScript in the WebView2 environment to power its features.
|
||||
|
||||
WebView2Browser shows some of the simplest uses of WebView2 -such as creating and navigating a WebView, but also some more complex workflows like using the [PostWebMessageAsJson API](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webview#postwebmessageasjson) to communicate WebViews in separate environments. It is intended as a rich code sample to look at how you can use WebView2 APIs to build your own app.
|
||||
WebView2Browser shows some of the simplest uses of WebView2 -such as creating and navigating a WebView, but also some more complex workflows like using the [PostWebMessageAsJson API](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2#postwebmessageasjson) to communicate WebViews in separate environments. It is intended as a rich code sample to look at how you can use WebView2 APIs to build your own app.
|
||||
|
||||
## Requisites
|
||||
- [Microsoft Edge (Chromium)](https://www.microsoftedgeinsider.com/en-us/download/) installed on a supported OS.
|
||||
- [Microsoft Edge (Chromium)](https://www.microsoftedgeinsider.com/download/) installed on a supported OS.
|
||||
- [Visual Studio](https://visualstudio.microsoft.com/vs/) with C++ support installed.
|
||||
|
||||
The Edge Canary channel is recommended for the installation and the minimum version is 78.0.240.0.
|
||||
The Edge Canary channel is recommended for the installation and the minimum version is 82.0.430.0.
|
||||
|
||||
## Build the browser
|
||||
Clone the repository and open the solution in Visual Studio. WebView2 is already included as a NuGet package* in the project!
|
||||
|
@ -50,7 +50,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
|
|||
// ...
|
||||
```
|
||||
|
||||
In `WebViewBrowser.cpp`, you will need to remove the call to `GetDpiForWindow`.
|
||||
In `BrowserWindow.cpp`, you will need to remove the call to `GetDpiForWindow`.
|
||||
```cpp
|
||||
int BrowserWindow::GetDPIAwareBound(int bound)
|
||||
{
|
||||
|
@ -82,30 +82,38 @@ WebView2Browser provides all the functionalities to make a basic web browser, bu
|
|||
- Clearing cache and cookies
|
||||
|
||||
## WebView2 APIs
|
||||
WebView2Browser makes use of a handful of the APIs available in WebView2. For the APIs not used here, you can find more about them in the [Microsoft Edge WebView2 Reference](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference-webview2). The following is a list of the most interesting APIs WebView2Browser uses and the feature(s) they enable.
|
||||
WebView2Browser makes use of a handful of the APIs available in WebView2. For the APIs not used here, you can find more about them in the [Microsoft Edge WebView2 Reference](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference-webview2). The following is a list of the most interesting APIs WebView2Browser uses and the feature(s) they enable.
|
||||
|
||||
API | Feature(s)
|
||||
:--- | :---
|
||||
CreateWebView2EnvironmentWithDetails | Used to create the environments for UI and content WebViews. Different user data directories are passed to isolate UI from web content. |
|
||||
IWebView2DevToolsProtocolEventReceivedEventHandler | Used along with add_DevToolsProtocolEventReceived to listen for CDP security events to update the lock icon in the browser UI. |
|
||||
IWebView2DocumentStateChangedEventHandler | Used along with add_DocumentStateChanged to udpate the address bar and navigation buttons in the browser UI. |
|
||||
IWebView2ExecuteScriptCompletedHandler | Used along with ExecuteScript to get the title and favicon from the visited page. |
|
||||
IWebView2FocusChangedEventHandler | Used along with add_LostFocus to hide the browser options dropdown when it loses focus.
|
||||
IWebView2NavigationCompletedEventHandler | Used along with add_NavigationCompleted to udpate the reload button in the browser UI.
|
||||
IWebView2Settings | Used to disable DevTools in the browser UI.
|
||||
IWebView2WebMessageReceivedEventHandler | This is one of the most important APIs to WebView2Browser. Most functionalities involving communication across WebViews use this.
|
||||
IWebView2WebView | There are several WebViews in WebView2Browser and most features make use of members in this interface, the table below shows how they're used.
|
||||
CreateCoreWebView2EnvironmentWithDetails | Used to create the environments for UI and content WebViews. Different user data directories are passed to isolate UI from web content. |
|
||||
ICoreWebView2 | There are several WebViews in WebView2Browser and most features make use of members in this interface, the table below shows how they're used.
|
||||
ICoreWebView2DevToolsProtocolEventReceivedEventHandler | Used along with add_DevToolsProtocolEventReceived to listen for CDP security events to update the lock icon in the browser UI. |
|
||||
ICoreWebView2DevToolsProtocolEventReceiver | Used along with add_DevToolsProtocolEventReceived to listen for CDP security events to update the lock icon in the browser UI. |
|
||||
ICoreWebView2ExecuteScriptCompletedHandler | Used along with ExecuteScript to get the title and favicon from the visited page. |
|
||||
ICoreWebView2FocusChangedEventHandler | Used along with add_LostFocus to hide the browser options dropdown when it loses focus.
|
||||
ICoreWebView2HistoryChangedEventHandler | Used along with add_HistoryChanged to udpate the navigation buttons in the browser UI. |
|
||||
ICoreWebView2Host | There are several WebViewHosts in WebView2Browser and we fetch the associated WebViews from them.
|
||||
ICoreWebView2NavigationCompletedEventHandler | Used along with add_NavigationCompleted to udpate the reload button in the browser UI.
|
||||
ICoreWebView2Settings | Used to disable DevTools in the browser UI.
|
||||
ICoreWebView2SourceChangedEventHandler | Used along with add_SourceChanged to udpate the address bar in the browser UI. |
|
||||
ICoreWebView2WebMessageReceivedEventHandler | This is one of the most important APIs to WebView2Browser. Most functionalities involving communication across WebViews use this.
|
||||
|
||||
IWebView2WebView API | Feature(s)
|
||||
ICoreWebView2 API | Feature(s)
|
||||
:--- | :---
|
||||
add_NavigationStarting | Used to display the cancel navigation button in the controls WebView.
|
||||
add_DocumentStateChanged | Used to update the address bar and go back/forward buttons.
|
||||
add_SourceChanged | Used to update the address bar.
|
||||
add_HistoryChanged | Used to update go back/forward buttons.
|
||||
add_NavigationCompleted | Used to display the reload button once a navigation completes.
|
||||
add_LostFocus | Used to hide the options dropdown when the user clicks away of it.
|
||||
ExecuteScript | Used to get the title and favicon of a visited page.
|
||||
PostWebMessageAsJson | Used to communicate WebViews. All messages use JSON to pass parameters needed.
|
||||
add_WebMessageReceived | Used to handle web messages posted to the WebView.
|
||||
CallDevToolsProtocolMethod | Used to enable listening for security events, which will notify of security status changes in a document.
|
||||
|
||||
ICoreWebView2Host API | Feature(s)
|
||||
:--- | :---
|
||||
get_CoreWebView2 | Used to get the CoreWebView2 associated with this CoreWebView2Host.
|
||||
add_LostFocus | Used to hide the options dropdown when the user clicks away of it.
|
||||
<br />
|
||||
|
||||
## Implementing the features
|
||||
|
@ -125,7 +133,7 @@ The sections below describe how some of the features in WebView2Browser were imp
|
|||
|
||||
## The basics
|
||||
### Set up the environment, create a WebView
|
||||
WebView2 allows you to host web content in your Windows app. It exposes the globals [CreateWebView2Environment](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/webview2.idl#createwebview2environment) and [CreateWebView2EnvironmentWithDetails](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/webview2.idl#createwebview2environmentwithdetails) from which we can create the two separate environments for the browser's UI and content.
|
||||
WebView2 allows you to host web content in your Windows app. It exposes the globals [CreateCoreWebView2Environment](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/webview2.idl#createcorewebview2environment) and [CreateCoreWebView2EnvironmentWithDetails](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/webview2.idl#createcorewebview2environmentwithdetails) from which we can create the two separate environments for the browser's UI and content.
|
||||
|
||||
```cpp
|
||||
// Get directory for user data. This will be kept separated from the
|
||||
|
@ -137,9 +145,9 @@ WebView2 allows you to host web content in your Windows app. It exposes the glob
|
|||
// tabs will be created from this environment and kept isolated from the
|
||||
// browser UI. This enviroment is created first so the UI can request new
|
||||
// tabs when it's ready.
|
||||
HRESULT hr = CreateWebView2EnvironmentWithDetails(nullptr, userDataDirectory.c_str(), WEBVIEW2_RELEASE_CHANNEL_PREFERENCE_STABLE,
|
||||
L"", Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2Environment* env) -> HRESULT
|
||||
HRESULT hr = CreateCoreWebView2EnvironmentWithDetails(nullptr, userDataDirectory.c_str(),
|
||||
L"", Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT
|
||||
{
|
||||
RETURN_IF_FAILED(result);
|
||||
|
||||
|
@ -163,9 +171,9 @@ HRESULT BrowserWindow::InitUIWebViews()
|
|||
|
||||
// Create WebView environment for browser UI. A separate data directory is
|
||||
// used to isolate the browser UI from web content requested by the user.
|
||||
return CreateWebView2EnvironmentWithDetails(nullptr, browserDataDirectory.c_str(), WEBVIEW2_RELEASE_CHANNEL_PREFERENCE_STABLE,
|
||||
L"", Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2Environment* env) -> HRESULT
|
||||
return CreateCoreWebView2EnvironmentWithDetails(nullptr, browserDataDirectory.c_str(),
|
||||
L"", Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT
|
||||
{
|
||||
// Environment is ready, create the WebView
|
||||
m_uiEnv = env;
|
||||
|
@ -178,13 +186,13 @@ HRESULT BrowserWindow::InitUIWebViews()
|
|||
}
|
||||
```
|
||||
|
||||
We use the [IWebView2CreateWebView2EnvironmentCompletedHandler](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2createwebview2environmentcompletedhandler#interface_i_web_view2_create_web_view2_environment_completed_handler) to create the UI WebViews once the environment is ready.
|
||||
We use the [ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2createcorewebview2environmentcompletedhandler) to create the UI WebViews once the environment is ready.
|
||||
|
||||
```cpp
|
||||
HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
||||
{
|
||||
return m_uiEnv->CreateWebView(m_hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2WebView* webview) -> HRESULT
|
||||
return m_uiEnv->CreateCoreWebView2Host(m_hWnd, Callback<ICoreWebView2CreateCoreWebView2HostCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Host* host) -> HRESULT
|
||||
{
|
||||
if (!SUCCEEDED(result))
|
||||
{
|
||||
|
@ -192,17 +200,17 @@ HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
|||
return result;
|
||||
}
|
||||
// WebView created
|
||||
m_controlsWebView = webview;
|
||||
m_controlsHost = host;
|
||||
CheckFailure(m_controlsHost->get_CoreWebView2(&m_controlsWebView), L"");
|
||||
|
||||
wil::com_ptr<IWebView2Settings> settings;
|
||||
wil::com_ptr<ICoreWebView2Settings> settings;
|
||||
RETURN_IF_FAILED(m_controlsWebView->get_Settings(&settings));
|
||||
RETURN_IF_FAILED(settings->put_AreDevToolsEnabled(FALSE));
|
||||
RETURN_IF_FAILED(settings->put_IsFullscreenAllowed(FALSE));
|
||||
|
||||
RETURN_IF_FAILED(m_controlsWebView->add_ZoomFactorChanged(Callback<IWebView2ZoomFactorChangedEventHandler>(
|
||||
[](IWebView2WebView* webview, IUnknown* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_controlsHost->add_ZoomFactorChanged(Callback<ICoreWebView2ZoomFactorChangedEventHandler>(
|
||||
[](ICoreWebView2Host* host, IUnknown* args) -> HRESULT
|
||||
{
|
||||
webview->put_ZoomFactor(1.0);
|
||||
host->put_ZoomFactor(1.0);
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), &m_controlsZoomToken));
|
||||
|
@ -217,7 +225,7 @@ HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
|||
}).Get());
|
||||
}
|
||||
```
|
||||
We're setting up a few things here. The [IWebView2Settings](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2settings) interface is used to disable DevTools in the WebView powering the browser controls. We're also adding a handler for received web messages. This handler will enable us to do something when the user interacts with the controls in this WebView.
|
||||
We're setting up a few things here. The [ICoreWebView2Settings](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2settings) interface is used to disable DevTools in the WebView powering the browser controls. We're also adding a handler for received web messages. This handler will enable us to do something when the user interacts with the controls in this WebView.
|
||||
|
||||
### Navigate to web page
|
||||
You can navigate to a web page by entering its URI in the address bar. When pressing Enter, the controls WebView will post a web message to the host app so it can navigate the active tab to the specified location. Code below shows how the host Win32 application will handle that message.
|
||||
|
@ -261,8 +269,8 @@ The address bar is updated every time there is a change in the active tab's docu
|
|||
|
||||
```cpp
|
||||
// Register event handler for doc state change
|
||||
RETURN_IF_FAILED(m_contentWebView->add_DocumentStateChanged(Callback<IWebView2DocumentStateChangedEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_contentWebView->add_SourceChanged(Callback<ICoreWebView2SourceChangedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2SourceChangedEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabURIUpdate(m_tabId, webview), L"Can't update address bar");
|
||||
|
||||
|
@ -270,7 +278,7 @@ The address bar is updated every time there is a change in the active tab's docu
|
|||
}).Get(), &m_uriUpdateForwarderToken));
|
||||
```
|
||||
```cpp
|
||||
HRESULT BrowserWindow::HandleTabURIUpdate(size_t tabId, IWebView2WebView* webview)
|
||||
HRESULT BrowserWindow::HandleTabURIUpdate(size_t tabId, ICoreWebView2* webview)
|
||||
{
|
||||
wil::unique_cotaskmem_string source;
|
||||
RETURN_IF_FAILED(webview->get_Source(&source));
|
||||
|
@ -283,6 +291,15 @@ HRESULT BrowserWindow::HandleTabURIUpdate(size_t tabId, IWebView2WebView* webvie
|
|||
|
||||
// ...
|
||||
|
||||
RETURN_IF_FAILED(PostJsonToWebView(jsonObj, m_controlsWebView.Get()));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BrowserWindow::HandleTabHistoryUpdate(size_t tabId, ICoreWebView2* webview)
|
||||
{
|
||||
// ...
|
||||
|
||||
BOOL canGoForward = FALSE;
|
||||
RETURN_IF_FAILED(webview->get_CanGoForward(&canGoForward));
|
||||
jsonObj[L"args"][L"canGoForward"] = web::json::value::boolean(canGoForward);
|
||||
|
@ -398,12 +415,12 @@ function reloadActiveTabContent() {
|
|||
|
||||
## Some interesting features
|
||||
### Communicating the WebViews
|
||||
We need to communicate the WebViews powering tabs and UI so that user interactions in one have the desired effect in the other. WebView2Browser makes use of set of very useful WebView2 APIs for this purpose, including [PostWebMessageAsJson](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webview#postwebmessageasjson), [add_WebMessageReceived](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webview#add_webmessagereceived) and [IWebView2WebMessageReceivedEventHandler](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webmessagereceivedeventhandler). On the JavaScript side, we're making use of the `window.chrome.webview` object exposed to call the `postMessage` method and add an event lister for received messages.
|
||||
We need to communicate the WebViews powering tabs and UI so that user interactions in one have the desired effect in the other. WebView2Browser makes use of set of very useful WebView2 APIs for this purpose, including [PostWebMessageAsJson](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2#postwebmessageasjson), [add_WebMessageReceived](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2#add_webmessagereceived) and [ICoreWebView2WebMessageReceivedEventHandler](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2webmessagereceivedeventhandler). On the JavaScript side, we're making use of the `window.chrome.webview` object exposed to call the `postMessage` method and add an event lister for received messages.
|
||||
```cpp
|
||||
HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
||||
{
|
||||
return m_uiEnv->CreateWebView(m_hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
|
||||
[this](HRESULT result, IWebView2WebView* webview) -> HRESULT
|
||||
return m_uiEnv->CreateCoreWebView2Host(m_hWnd, Callback<ICoreWebView2CreateCoreWebView2HostCompletedHandler>(
|
||||
[this](HRESULT result, ICoreWebView2Host* host) -> HRESULT
|
||||
{
|
||||
// ...
|
||||
|
||||
|
@ -416,7 +433,7 @@ HRESULT BrowserWindow::CreateBrowserControlsWebView()
|
|||
}
|
||||
```
|
||||
```cpp
|
||||
HRESULT BrowserWindow::PostJsonToWebView(web::json::value jsonObj, IWebView2WebView* webview)
|
||||
HRESULT BrowserWindow::PostJsonToWebView(web::json::value jsonObj, ICoreWebView2* webview)
|
||||
{
|
||||
utility::stringstream_t stream;
|
||||
jsonObj.serialize(stream);
|
||||
|
@ -426,7 +443,7 @@ HRESULT BrowserWindow::PostJsonToWebView(web::json::value jsonObj, IWebView2WebV
|
|||
|
||||
// ...
|
||||
|
||||
HRESULT BrowserWindow::HandleTabNavStarting(size_t tabId, IWebView2WebView* webview)
|
||||
HRESULT BrowserWindow::HandleTabNavStarting(size_t tabId, ICoreWebView2* webview)
|
||||
{
|
||||
web::json::value jsonObj = web::json::value::parse(L"{}");
|
||||
jsonObj[L"message"] = web::json::value(MG_NAV_STARTING);
|
||||
|
@ -491,7 +508,7 @@ function createNewTab(shouldBeActive) {
|
|||
}
|
||||
}
|
||||
```
|
||||
On the host app side, the registered [IWebView2WebMessageReceivedEventHandler](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webmessagereceivedeventhandler) will catch the message and create the WebView for that tab.
|
||||
On the host app side, the registered [ICoreWebView2WebMessageReceivedEventHandler](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2webmessagereceivedeventhandler) will catch the message and create the WebView for that tab.
|
||||
```cpp
|
||||
case MG_CREATE_TAB:
|
||||
{
|
||||
|
@ -513,7 +530,7 @@ On the host app side, the registered [IWebView2WebMessageReceivedEventHandler](h
|
|||
break;
|
||||
```
|
||||
```cpp
|
||||
std::unique_ptr<Tab> Tab::CreateNewTab(HWND hWnd, IWebView2Environment* env, size_t id, bool shouldBeActive)
|
||||
std::unique_ptr<Tab> Tab::CreateNewTab(HWND hWnd, ICoreWebView2Environment* env, size_t id, bool shouldBeActive)
|
||||
{
|
||||
std::unique_ptr<Tab> tab = std::make_unique<Tab>();
|
||||
|
||||
|
@ -525,38 +542,48 @@ std::unique_ptr<Tab> Tab::CreateNewTab(HWND hWnd, IWebView2Environment* env, siz
|
|||
return tab;
|
||||
}
|
||||
|
||||
HRESULT Tab::Init(IWebView2Environment* env, bool shouldBeActive)
|
||||
HRESULT Tab::Init(ICoreWebView2Environment* env, bool shouldBeActive)
|
||||
{
|
||||
return env->CreateWebView(m_parentHWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
|
||||
[this, shouldBeActive](HRESULT result, IWebView2WebView* webview) -> HRESULT {
|
||||
return env->CreateCoreWebView2Host(m_parentHWnd, Callback<ICoreWebView2CreateCoreWebView2HostCompletedHandler>(
|
||||
[this, shouldBeActive](HRESULT result, ICoreWebView2Host* host) -> HRESULT {
|
||||
if (!SUCCEEDED(result))
|
||||
{
|
||||
OutputDebugString(L"Tab WebView creation failed\n");
|
||||
return result;
|
||||
}
|
||||
m_contentWebView = webview;
|
||||
m_contentHost = host;
|
||||
BrowserWindow::CheckFailure(m_contentHost->get_CoreWebView2(&m_contentWebView), L"");
|
||||
BrowserWindow* browserWindow = reinterpret_cast<BrowserWindow*>(GetWindowLongPtr(m_parentHWnd, GWLP_USERDATA));
|
||||
RETURN_IF_FAILED(m_contentWebView->add_WebMessageReceived(m_messageBroker.Get(), &m_messageBrokerToken));
|
||||
|
||||
// Register event handler for doc state change
|
||||
RETURN_IF_FAILED(m_contentWebView->add_DocumentStateChanged(Callback<IWebView2DocumentStateChangedEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
|
||||
// Register event handler for history change
|
||||
RETURN_IF_FAILED(m_contentWebView->add_HistoryChanged(Callback<ICoreWebView2HistoryChangedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, IUnknown* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabHistoryUpdate(m_tabId, webview), L"Can't update go back/forward buttons.");
|
||||
|
||||
return S_OK;
|
||||
}).Get(), &m_historyUpdateForwarderToken));
|
||||
|
||||
// Register event handler for source change
|
||||
RETURN_IF_FAILED(m_contentWebView->add_SourceChanged(Callback<ICoreWebView2SourceChangedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2SourceChangedEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabURIUpdate(m_tabId, webview), L"Can't update address bar");
|
||||
|
||||
return S_OK;
|
||||
}).Get(), &m_uriUpdateForwarderToken));
|
||||
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationStarting(Callback<IWebView2NavigationStartingEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationStarting(Callback<ICoreWebView2NavigationStartingEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabNavStarting(m_tabId, webview), L"Can't update reload button");
|
||||
|
||||
return S_OK;
|
||||
}).Get(), &m_navStartingToken));
|
||||
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationCompleted(Callback<IWebView2NavigationCompletedEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2NavigationCompletedEventArgs* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationCompleted(Callback<ICoreWebView2NavigationCompletedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2NavigationCompletedEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabNavCompleted(m_tabId, webview, args), L"Can't udpate reload button");
|
||||
return S_OK;
|
||||
|
@ -591,21 +618,23 @@ HRESULT BrowserWindow::SwitchToTab(size_t tabId)
|
|||
```
|
||||
|
||||
### Updating the security icon
|
||||
We use the [CallDevToolsProtocolMethod](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webview#calldevtoolsprotocolmethod) to enable listening for security events. Whenever a `securityStateChanged` event is fired, we will use the new state to update the security icon on the controls WebView.
|
||||
We use the [CallDevToolsProtocolMethod](https://docs.microsoft.com/microsoft-edge/hosting/webview2/reference/icorewebview2#calldevtoolsprotocolmethod) to enable listening for security events. Whenever a `securityStateChanged` event is fired, we will use the new state to update the security icon on the controls WebView.
|
||||
```cpp
|
||||
// Enable listening for security events to update secure icon
|
||||
RETURN_IF_FAILED(m_contentWebView->CallDevToolsProtocolMethod(L"Security.enable", L"{}", nullptr));
|
||||
|
||||
BrowserWindow::CheckFailure(m_contentWebView->GetDevToolsProtocolEventReceiver(L"Security.securityStateChanged", &m_securityStateChangedReceiver), L"");
|
||||
|
||||
// Forward security status updates to browser
|
||||
RETURN_IF_FAILED(m_contentWebView->add_DevToolsProtocolEventReceived(L"Security.securityStateChanged", Callback<IWebView2DevToolsProtocolEventReceivedEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2DevToolsProtocolEventReceivedEventArgs* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_securityStateChangedReceiver->add_DevToolsProtocolEventReceived(Callback<ICoreWebView2DevToolsProtocolEventReceivedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2DevToolsProtocolEventReceivedEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabSecurityUpdate(m_tabId, webview, args), L"Can't udpate security icon");
|
||||
return S_OK;
|
||||
}).Get(), &m_securityUpdateToken));
|
||||
```
|
||||
```cpp
|
||||
HRESULT BrowserWindow::HandleTabSecurityUpdate(size_t tabId, IWebView2WebView* webview, IWebView2DevToolsProtocolEventReceivedEventArgs* args)
|
||||
HRESULT BrowserWindow::HandleTabSecurityUpdate(size_t tabId, ICoreWebView2* webview, ICoreWebView2DevToolsProtocolEventReceivedEventArgs* args)
|
||||
{
|
||||
wil::unique_cotaskmem_string jsonArgs;
|
||||
RETURN_IF_FAILED(args->get_ParameterObjectAsJson(&jsonArgs));
|
||||
|
|
46
Tab.cpp
46
Tab.cpp
|
@ -7,7 +7,7 @@
|
|||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
std::unique_ptr<Tab> Tab::CreateNewTab(HWND hWnd, IWebView2Environment* env, size_t id, bool shouldBeActive)
|
||||
std::unique_ptr<Tab> Tab::CreateNewTab(HWND hWnd, ICoreWebView2Environment* env, size_t id, bool shouldBeActive)
|
||||
{
|
||||
std::unique_ptr<Tab> tab = std::make_unique<Tab>();
|
||||
|
||||
|
@ -19,38 +19,48 @@ std::unique_ptr<Tab> Tab::CreateNewTab(HWND hWnd, IWebView2Environment* env, siz
|
|||
return tab;
|
||||
}
|
||||
|
||||
HRESULT Tab::Init(IWebView2Environment* env, bool shouldBeActive)
|
||||
HRESULT Tab::Init(ICoreWebView2Environment* env, bool shouldBeActive)
|
||||
{
|
||||
return env->CreateWebView(m_parentHWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
|
||||
[this, shouldBeActive](HRESULT result, IWebView2WebView* webview) -> HRESULT {
|
||||
return env->CreateCoreWebView2Host(m_parentHWnd, Callback<ICoreWebView2CreateCoreWebView2HostCompletedHandler>(
|
||||
[this, shouldBeActive](HRESULT result, ICoreWebView2Host* host) -> HRESULT {
|
||||
if (!SUCCEEDED(result))
|
||||
{
|
||||
OutputDebugString(L"Tab WebView creation failed\n");
|
||||
return result;
|
||||
}
|
||||
m_contentWebView = webview;
|
||||
m_contentHost = host;
|
||||
BrowserWindow::CheckFailure(m_contentHost->get_CoreWebView2(&m_contentWebView), L"");
|
||||
BrowserWindow* browserWindow = reinterpret_cast<BrowserWindow*>(GetWindowLongPtr(m_parentHWnd, GWLP_USERDATA));
|
||||
RETURN_IF_FAILED(m_contentWebView->add_WebMessageReceived(m_messageBroker.Get(), &m_messageBrokerToken));
|
||||
|
||||
// Register event handler for doc state change
|
||||
RETURN_IF_FAILED(m_contentWebView->add_DocumentStateChanged(Callback<IWebView2DocumentStateChangedEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
|
||||
// Register event handler for history change
|
||||
RETURN_IF_FAILED(m_contentWebView->add_HistoryChanged(Callback<ICoreWebView2HistoryChangedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, IUnknown* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabHistoryUpdate(m_tabId, webview), L"Can't update go back/forward buttons.");
|
||||
|
||||
return S_OK;
|
||||
}).Get(), &m_historyUpdateForwarderToken));
|
||||
|
||||
// Register event handler for source change
|
||||
RETURN_IF_FAILED(m_contentWebView->add_SourceChanged(Callback<ICoreWebView2SourceChangedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2SourceChangedEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabURIUpdate(m_tabId, webview), L"Can't update address bar");
|
||||
|
||||
return S_OK;
|
||||
}).Get(), &m_uriUpdateForwarderToken));
|
||||
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationStarting(Callback<IWebView2NavigationStartingEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationStarting(Callback<ICoreWebView2NavigationStartingEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabNavStarting(m_tabId, webview), L"Can't update reload button");
|
||||
|
||||
return S_OK;
|
||||
}).Get(), &m_navStartingToken));
|
||||
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationCompleted(Callback<IWebView2NavigationCompletedEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2NavigationCompletedEventArgs* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_contentWebView->add_NavigationCompleted(Callback<ICoreWebView2NavigationCompletedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2NavigationCompletedEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabNavCompleted(m_tabId, webview, args), L"Can't udpate reload button");
|
||||
return S_OK;
|
||||
|
@ -59,9 +69,11 @@ HRESULT Tab::Init(IWebView2Environment* env, bool shouldBeActive)
|
|||
// Enable listening for security events to update secure icon
|
||||
RETURN_IF_FAILED(m_contentWebView->CallDevToolsProtocolMethod(L"Security.enable", L"{}", nullptr));
|
||||
|
||||
BrowserWindow::CheckFailure(m_contentWebView->GetDevToolsProtocolEventReceiver(L"Security.securityStateChanged", &m_securityStateChangedReceiver), L"");
|
||||
|
||||
// Forward security status updates to browser
|
||||
RETURN_IF_FAILED(m_contentWebView->add_DevToolsProtocolEventReceived(L"Security.securityStateChanged", Callback<IWebView2DevToolsProtocolEventReceivedEventHandler>(
|
||||
[this, browserWindow](IWebView2WebView* webview, IWebView2DevToolsProtocolEventReceivedEventArgs* args) -> HRESULT
|
||||
RETURN_IF_FAILED(m_securityStateChangedReceiver->add_DevToolsProtocolEventReceived(Callback<ICoreWebView2DevToolsProtocolEventReceivedEventHandler>(
|
||||
[this, browserWindow](ICoreWebView2* webview, ICoreWebView2DevToolsProtocolEventReceivedEventArgs* args) -> HRESULT
|
||||
{
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabSecurityUpdate(m_tabId, webview, args), L"Can't udpate security icon");
|
||||
return S_OK;
|
||||
|
@ -76,8 +88,8 @@ HRESULT Tab::Init(IWebView2Environment* env, bool shouldBeActive)
|
|||
|
||||
void Tab::SetMessageBroker()
|
||||
{
|
||||
m_messageBroker = Callback<IWebView2WebMessageReceivedEventHandler>(
|
||||
[this](IWebView2WebView* webview, IWebView2WebMessageReceivedEventArgs* eventArgs) -> HRESULT
|
||||
m_messageBroker = Callback<ICoreWebView2WebMessageReceivedEventHandler>(
|
||||
[this](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* eventArgs) -> HRESULT
|
||||
{
|
||||
BrowserWindow* browserWindow = reinterpret_cast<BrowserWindow*>(GetWindowLongPtr(m_parentHWnd, GWLP_USERDATA));
|
||||
BrowserWindow::CheckFailure(browserWindow->HandleTabMessageReceived(m_tabId, webview, eventArgs), L"");
|
||||
|
@ -94,5 +106,5 @@ HRESULT Tab::ResizeWebView()
|
|||
BrowserWindow* browserWindow = reinterpret_cast<BrowserWindow*>(GetWindowLongPtr(m_parentHWnd, GWLP_USERDATA));
|
||||
bounds.top += browserWindow->GetDPIAwareBound(BrowserWindow::c_uiBarHeight);
|
||||
|
||||
return m_contentWebView->put_Bounds(bounds);
|
||||
return m_contentHost->put_Bounds(bounds);
|
||||
}
|
||||
|
|
11
Tab.h
11
Tab.h
|
@ -9,20 +9,23 @@
|
|||
class Tab
|
||||
{
|
||||
public:
|
||||
Microsoft::WRL::ComPtr<IWebView2WebView> m_contentWebView;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2Host> m_contentHost;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2> m_contentWebView;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2DevToolsProtocolEventReceiver> m_securityStateChangedReceiver;
|
||||
|
||||
static std::unique_ptr<Tab> CreateNewTab(HWND hWnd, IWebView2Environment* env, size_t id, bool shouldBeActive);
|
||||
static std::unique_ptr<Tab> CreateNewTab(HWND hWnd, ICoreWebView2Environment* env, size_t id, bool shouldBeActive);
|
||||
HRESULT ResizeWebView();
|
||||
protected:
|
||||
HWND m_parentHWnd = nullptr;
|
||||
size_t m_tabId = INVALID_TAB_ID;
|
||||
EventRegistrationToken m_historyUpdateForwarderToken = {};
|
||||
EventRegistrationToken m_uriUpdateForwarderToken = {};
|
||||
EventRegistrationToken m_navStartingToken = {};
|
||||
EventRegistrationToken m_navCompletedToken = {};
|
||||
EventRegistrationToken m_securityUpdateToken = {};
|
||||
EventRegistrationToken m_messageBrokerToken = {}; // Message broker for browser pages loaded in a tab
|
||||
Microsoft::WRL::ComPtr<IWebView2WebMessageReceivedEventHandler> m_messageBroker;
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebMessageReceivedEventHandler> m_messageBroker;
|
||||
|
||||
HRESULT Init(IWebView2Environment* env, bool shouldBeActive);
|
||||
HRESULT Init(ICoreWebView2Environment* env, bool shouldBeActive);
|
||||
void SetMessageBroker();
|
||||
};
|
||||
|
|
|
@ -13,14 +13,10 @@ Global
|
|||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Debug|x64.Build.0 = Debug|x64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Release|x64.ActiveCfg = Release|x64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Release|x64.Build.0 = Release|x64
|
||||
{D65018E5-6B31-4DC7-AFAC-7999384BA4BD}.Release|x86.ActiveCfg = Release|Win32
|
||||
|
|
|
@ -17,14 +17,6 @@
|
|||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
|
@ -61,19 +53,6 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
@ -91,12 +70,6 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
|
@ -111,13 +84,6 @@
|
|||
<TargetName>$(ProjectName)</TargetName>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(Configuration)_$(Platform)</OutDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(Configuration)_x86</OutDir>
|
||||
|
@ -130,12 +96,6 @@
|
|||
<TargetName>$(ProjectName)</TargetName>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(Configuration)_$(Platform)</OutDir>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
|
@ -145,7 +105,6 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -164,28 +123,6 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(ProjectDir)wvbrowser_ui" "$(OutDir)wvbrowser_ui" /S /I /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -208,7 +145,6 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -231,30 +167,6 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(ProjectDir)wvbrowser_ui" "$(OutDir)wvbrowser_ui" /S /I /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -294,7 +206,7 @@
|
|||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="packages\Microsoft.Windows.ImplementationLibrary.1.0.190610.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('packages\Microsoft.Windows.ImplementationLibrary.1.0.190610.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="packages\cpprestsdk.v141.2.10.12.1\build\native\cpprestsdk.v141.targets" Condition="Exists('packages\cpprestsdk.v141.2.10.12.1\build\native\cpprestsdk.v141.targets')" />
|
||||
<Import Project="packages\Microsoft.Web.WebView2.0.8.270\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('packages\Microsoft.Web.WebView2.0.8.270\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
<Import Project="packages\Microsoft.Web.WebView2.0.9.430\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('packages\Microsoft.Web.WebView2.0.9.430\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
@ -302,6 +214,6 @@
|
|||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\Microsoft.Windows.ImplementationLibrary.1.0.190610.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Windows.ImplementationLibrary.1.0.190610.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('packages\cpprestsdk.v141.2.10.12.1\build\native\cpprestsdk.v141.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cpprestsdk.v141.2.10.12.1\build\native\cpprestsdk.v141.targets'))" />
|
||||
<Error Condition="!Exists('packages\Microsoft.Web.WebView2.0.8.270\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Web.WebView2.0.8.270\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
<Error Condition="!Exists('packages\Microsoft.Web.WebView2.0.9.430\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Web.WebView2.0.9.430\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="cpprestsdk.v141" version="2.10.12.1" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="0.8.270" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="0.9.430" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190610.2" targetFramework="native" />
|
||||
</packages>
|
Загрузка…
Ссылка в новой задаче