Skip to content

Commit 298b0a5

Browse files
committed
Move projects to use latest WebView2 SDK 0.9.627-prerelease
1 parent 6bea00d commit 298b0a5

28 files changed

+281
-697
lines changed

SampleApps/WebView2APISample/App.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <shobjidl.h>
1313
#include <string.h>
1414
#include <vector>
15+
1516
#include "AppWindow.h"
1617
#include "DpiUtil.h"
1718

@@ -101,6 +102,10 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
101102
{
102103
creationModeId = IDM_CREATION_MODE_VISUAL_DCOMP;
103104
}
105+
else if (NEXT_PARAM_CONTAINS(L"targetdcomp"))
106+
{
107+
creationModeId = IDM_CREATION_MODE_TARGET_DCOMP;
108+
}
104109
else if (NEXT_PARAM_CONTAINS(L"visualwincomp"))
105110
{
106111
creationModeId = IDM_CREATION_MODE_VISUAL_WINCOMP;

SampleApps/WebView2APISample/AppWindow.cpp

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66

77
#include "AppWindow.h"
88

9+
#include <DispatcherQueue.h>
910
#include <functional>
1011
#include <string>
1112
#include <vector>
1213
#include <ShObjIdl_core.h>
1314
#include <Shellapi.h>
1415
#include <ShlObj_core.h>
16+
#include <winrt/windows.system.h>
1517
#include "App.h"
1618
#include "CheckFailure.h"
1719
#include "ControlComponent.h"
@@ -48,6 +50,9 @@ AppWindow::AppWindow(
4850
m_initialUri(initialUri),
4951
m_onWebViewFirstInitialized(webviewCreatedCallback)
5052
{
53+
// Initialize COM as STA.
54+
CHECK_FAILURE(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));
55+
5156
++s_appInstances;
5257

5358
WCHAR szTitle[s_maxLoadString]; // The title bar text
@@ -328,6 +333,7 @@ bool AppWindow::ExecuteAppCommands(WPARAM wParam, LPARAM lParam)
328333
return true;
329334
case IDM_CREATION_MODE_WINDOWED:
330335
case IDM_CREATION_MODE_VISUAL_DCOMP:
336+
case IDM_CREATION_MODE_TARGET_DCOMP:
331337
case IDM_CREATION_MODE_VISUAL_WINCOMP:
332338
m_creationModeId = LOWORD(wParam);
333339
UpdateCreationModeMenu();
@@ -446,10 +452,11 @@ void AppWindow::InitializeWebView()
446452
// getting created which will apply the browser switches.
447453
CloseWebView();
448454
m_dcompDevice = nullptr;
449-
m_wincompHelper = nullptr;
455+
m_wincompCompositor = nullptr;
450456
LPCWSTR subFolder = nullptr;
451457

452-
if (m_creationModeId == IDM_CREATION_MODE_VISUAL_DCOMP)
458+
if (m_creationModeId == IDM_CREATION_MODE_VISUAL_DCOMP ||
459+
m_creationModeId == IDM_CREATION_MODE_TARGET_DCOMP)
453460
{
454461
HRESULT hr = DCompositionCreateDevice2(nullptr, IID_PPV_ARGS(&m_dcompDevice));
455462
if (!SUCCEEDED(hr))
@@ -465,7 +472,7 @@ void AppWindow::InitializeWebView()
465472
}
466473
else if (m_creationModeId == IDM_CREATION_MODE_VISUAL_WINCOMP)
467474
{
468-
HRESULT hr = CreateWinCompCompositor();
475+
HRESULT hr = TryCreateDispatcherQueue();
469476
if (!SUCCEEDED(hr))
470477
{
471478
MessageBox(
@@ -476,10 +483,11 @@ void AppWindow::InitializeWebView()
476483
L"Create with Windowless WinComp Visual Failed", MB_OK);
477484
return;
478485
}
486+
m_wincompCompositor = winrtComp::Compositor();
479487
}
480488
//! [CreateCoreWebView2EnvironmentWithOptions]
481-
auto options = Microsoft::WRL::Make<CoreWebView2ExperimentalEnvironmentOptions>();
482-
CHECK_FAILURE(options->put_IsSingleSignOnUsingOSPrimaryAccountEnabled(
489+
auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
490+
CHECK_FAILURE(options->put_AllowSingleSignOnUsingOSPrimaryAccount(
483491
m_AADSSOEnabled ? TRUE : FALSE));
484492
if (!m_language.empty())
485493
CHECK_FAILURE(options->put_Language(m_language.c_str()));
@@ -516,7 +524,7 @@ HRESULT AppWindow::OnCreateEnvironmentCompleted(
516524

517525
auto webViewExperimentalEnvironment =
518526
m_webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment>();
519-
if (webViewExperimentalEnvironment && (m_dcompDevice || m_wincompHelper))
527+
if (webViewExperimentalEnvironment && (m_dcompDevice || m_wincompCompositor))
520528
{
521529
CHECK_FAILURE(webViewExperimentalEnvironment->CreateCoreWebView2CompositionController(
522530
m_mainWindow,
@@ -565,7 +573,9 @@ HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICore
565573
NewComponent<SettingsComponent>(
566574
this, m_webViewEnvironment.get(), m_oldSettingsComponent.get());
567575
m_oldSettingsComponent = nullptr;
568-
NewComponent<ViewComponent>(this, m_dcompDevice.get(), m_wincompHelper.get());
576+
NewComponent<ViewComponent>(
577+
this, m_dcompDevice.get(), m_wincompCompositor,
578+
m_creationModeId == IDM_CREATION_MODE_TARGET_DCOMP);
569579
NewComponent<ControlComponent>(this, &m_toolbar);
570580

571581
// We have a few of our own event handlers to register here as well
@@ -694,11 +704,8 @@ void AppWindow::RegisterEventHandlers()
694704
CHECK_FAILURE(args->GetDeferral(&deferral));
695705
AppWindow* newAppWindow;
696706

697-
wil::com_ptr<ICoreWebView2ExperimentalNewWindowRequestedEventArgs>
698-
experimentalArgs;
699-
CHECK_FAILURE(args->QueryInterface(IID_PPV_ARGS(&experimentalArgs)));
700-
wil::com_ptr<ICoreWebView2ExperimentalWindowFeatures> windowFeatures;
701-
CHECK_FAILURE(experimentalArgs->get_WindowFeatures(&windowFeatures));
707+
wil::com_ptr<ICoreWebView2WindowFeatures> windowFeatures;
708+
CHECK_FAILURE(args->get_WindowFeatures(&windowFeatures));
702709

703710
RECT windowRect = {0};
704711
UINT32 left = 0;
@@ -863,9 +870,6 @@ void AppWindow::CloseWebView(bool cleanupUserDataFolder)
863870

864871
HRESULT AppWindow::DeleteFileRecursive(std::wstring path)
865872
{
866-
// Initialize COM as STA.
867-
CHECK_FAILURE(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));
868-
869873
wil::com_ptr<IFileOperation> fileOperation;
870874
CHECK_FAILURE(
871875
CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&fileOperation)));
@@ -1030,37 +1034,49 @@ HRESULT AppWindow::DCompositionCreateDevice2(IUnknown* renderingDevice, REFIID r
10301034
return hr;
10311035
}
10321036

1033-
// Helper function that loads WebView2APISampleWinCompHelper.dll which provides an
1034-
// IWinCompHelper abstraction for building a WinComp visual tree. The DLL is dynamically
1035-
// loaded to create the helper interface and create the compositor. Not having a static
1036-
// dependency on WebView2APISampleWinCompHelper.dll enables the sample app to run on
1037-
// versions of Windows that don't support WinComp (since the DLL has a static dependency on
1038-
// WinComp).
1039-
HRESULT AppWindow::CreateWinCompCompositor()
1037+
// WinRT APIs cannot run without a DispatcherQueue. This helper function creates a
1038+
// DispatcherQueueController (which instantiates a DispatcherQueue under the covers) that will
1039+
// manage tasks for the WinRT APIs. The DispatcherQueue implementation lives in
1040+
// CoreMessaging.dll Similar to dcomp.dll, we load CoreMessaging.dll dynamically so the sample
1041+
// app can run on versions of windows that don't have CoreMessaging.
1042+
HRESULT AppWindow::TryCreateDispatcherQueue()
10401043
{
1041-
HRESULT hr = E_FAIL;
1042-
static decltype(::CreateWinCompHelper)* fnCreateWinCompHelper = nullptr;
1043-
if (fnCreateWinCompHelper == nullptr)
1044+
namespace winSystem = winrt::Windows::System;
1045+
1046+
HRESULT hr = S_OK;
1047+
thread_local winSystem::DispatcherQueueController dispatcherQueueController{ nullptr };
1048+
1049+
if (dispatcherQueueController == nullptr)
10441050
{
1045-
// Use SetErrorMode to ensure an error dialog doesn't pop up if the
1046-
// WebView2APISampleWinCompHelper.dll fails to load for a missing dependency.
1047-
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
1048-
HMODULE hmod = ::LoadLibraryEx(L"WebView2APISampleWinCompHelper.dll", nullptr, 0);
1049-
if (hmod != nullptr)
1051+
hr = E_FAIL;
1052+
static decltype(::CreateDispatcherQueueController)* fnCreateDispatcherQueueController =
1053+
nullptr;
1054+
if (fnCreateDispatcherQueueController == nullptr)
10501055
{
1051-
fnCreateWinCompHelper = reinterpret_cast<decltype(::CreateWinCompHelper)*>(
1052-
::GetProcAddress(hmod, "CreateWinCompHelper"));
1056+
HMODULE hmod = ::LoadLibraryEx(L"CoreMessaging.dll", nullptr, 0);
1057+
if (hmod != nullptr)
1058+
{
1059+
fnCreateDispatcherQueueController =
1060+
reinterpret_cast<decltype(::CreateDispatcherQueueController)*>(
1061+
::GetProcAddress(hmod, "CreateDispatcherQueueController"));
1062+
}
10531063
}
1054-
SetErrorMode(0);
1055-
}
1056-
if (fnCreateWinCompHelper != nullptr)
1057-
{
1058-
hr = fnCreateWinCompHelper(&m_wincompHelper);
1059-
if (SUCCEEDED(hr))
1064+
if (fnCreateDispatcherQueueController != nullptr)
10601065
{
1061-
hr = m_wincompHelper->CreateCompositor();
1066+
winSystem::DispatcherQueueController controller{ nullptr };
1067+
DispatcherQueueOptions options
1068+
{
1069+
sizeof(DispatcherQueueOptions),
1070+
DQTYPE_THREAD_CURRENT,
1071+
DQTAT_COM_STA
1072+
};
1073+
hr = fnCreateDispatcherQueueController(
1074+
options, reinterpret_cast<ABI::Windows::System::IDispatcherQueueController**>(
1075+
winrt::put_abi(controller)));
1076+
dispatcherQueueController = controller;
10621077
}
10631078
}
1079+
10641080
return hr;
10651081
}
10661082

SampleApps/WebView2APISample/AppWindow.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include <string>
1717
#include <vector>
1818
#include <winnt.h>
19-
#include "WebView2APISample_WinCompHelper/WebView2APISample_WinCompHelper.h"
19+
#include <winrt/Windows.UI.Composition.h>
2020
#include <winrt/Windows.UI.ViewManagement.h>
2121

22+
namespace winrtComp = winrt::Windows::UI::Composition;
23+
2224
class SettingsComponent;
2325

2426
class AppWindow
@@ -127,10 +129,10 @@ class AppWindow
127129

128130
// Compositor creation helper methods
129131
HRESULT DCompositionCreateDevice2(IUnknown* renderingDevice, REFIID riid, void** ppv);
130-
HRESULT CreateWinCompCompositor();
132+
HRESULT TryCreateDispatcherQueue();
131133

132134
wil::com_ptr<IDCompositionDevice> m_dcompDevice;
133-
wil::com_ptr<IWinCompHelper> m_wincompHelper;
135+
winrtComp::Compositor m_wincompCompositor{ nullptr };
134136
winrt::Windows::UI::ViewManagement::UISettings m_uiSettings{ nullptr };
135137
};
136138

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (C) Microsoft Corporation. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "stdafx.h"
6+
7+
#include "DCompTargetImpl.h"
8+
9+
DCompTargetImpl::DCompTargetImpl(ViewComponent* owner)
10+
{
11+
m_viewComponentOwner = owner;
12+
}
13+
14+
void DCompTargetImpl::RemoveOwnerRef()
15+
{
16+
m_viewComponentOwner = nullptr;
17+
}
18+
19+
HRESULT __stdcall DCompTargetImpl::SetRoot(IDCompositionVisual* visual)
20+
{
21+
HRESULT hr = S_OK;
22+
if (m_viewComponentOwner)
23+
{
24+
hr = m_viewComponentOwner->m_dcompWebViewVisual->RemoveAllVisuals();
25+
if (SUCCEEDED(hr) && visual)
26+
{
27+
hr = m_viewComponentOwner->m_dcompWebViewVisual->AddVisual(visual, FALSE, nullptr);
28+
}
29+
}
30+
31+
return hr;
32+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (C) Microsoft Corporation. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#pragma once
6+
7+
#include "stdafx.h"
8+
9+
#include "ViewComponent.h"
10+
11+
class DCompTargetImpl
12+
: public Microsoft::WRL::RuntimeClass<
13+
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IDCompositionTarget>
14+
{
15+
public:
16+
DCompTargetImpl(ViewComponent* owner);
17+
void RemoveOwnerRef();
18+
19+
// Inherited via IDCompositionTarget
20+
virtual HRESULT __stdcall SetRoot(IDCompositionVisual* visual) override;
21+
22+
private:
23+
ViewComponent* m_viewComponentOwner;
24+
};

SampleApps/WebView2APISample/ScenarioAddHostObject.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ <h2>Set Property</h2>
2121
<div><code><pre><span id="setPropertyAsyncOutput"></span></pre></code></div>
2222

2323
<button id="setPropertyExplicitAsyncButton">Set property explicit async</button><input type="text" id="setPropertyExplicitAsyncInput" placeholder="String property value" />
24-
<label for="setPropertyExplicitAsyncButton">Runs <code>await chrome.webview.hostObjects.sample.setRemote("property", value)</code> which waits for the property to be set.</label>
24+
<label for="setPropertyExplicitAsyncButton">Runs <code>await chrome.webview.hostObjects.sample.setHostProperty("property", value)</code> which waits for the property to be set.</label>
2525
<div><code><pre><span id="setPropertyExplicitAsyncOutput"></span></pre></code></div>
2626

2727
<button id="setPropertySyncButton">Set property sync</button><input type="text" id="setPropertySyncInput" placeholder="String property value" />
@@ -66,15 +66,15 @@ <h2>Invoke Callback</h2>
6666
document.getElementById("setPropertyAsyncButton").addEventListener("click", async () => {
6767
const propertyValue = document.getElementById("setPropertyAsyncInput").value;
6868
// The following line will work but it will return immediately before the property value has actually been set.
69-
// If you need to set the property and wait for the property to change value, use the setRemote function.
69+
// If you need to set the property and wait for the property to change value, use the setHostProperty function.
7070
chrome.webview.hostObjects.sample.property = propertyValue;
7171
document.getElementById("setPropertyAsyncOutput").textContent = "Set";
7272
});
7373

7474
document.getElementById("setPropertyExplicitAsyncButton").addEventListener("click", async () => {
7575
const propertyValue = document.getElementById("setPropertyExplicitAsyncInput").value;
76-
// If you care about waiting until the property has actually changed value use the setRemote function.
77-
await chrome.webview.hostObjects.sample.setRemote("property", propertyValue);
76+
// If you care about waiting until the property has actually changed value use the setHostProperty function.
77+
await chrome.webview.hostObjects.sample.setHostProperty("property", propertyValue);
7878
document.getElementById("setPropertyExplicitAsyncOutput").textContent = "Set";
7979
});
8080

0 commit comments

Comments
 (0)