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
864871HRESULT 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
0 commit comments