@@ -32,48 +32,50 @@ ScenarioAddHostObject::ScenarioAddHostObject(AppWindow* appWindow)
3232
3333 m_hostObject = Microsoft::WRL::Make<HostObjectSample>(
3434 [appWindow = m_appWindow](std::function<void (void )> callback)
35- {
36- appWindow->RunAsync (callback);
37- });
35+ { appWindow->RunAsync (callback); });
3836
3937 CHECK_FAILURE (m_webView->add_NavigationStarting (
4038 Microsoft::WRL::Callback<ICoreWebView2NavigationStartingEventHandler>(
41- [this , sampleUri](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT
42- {
43- wil::unique_cotaskmem_string navigationTargetUri;
44- CHECK_FAILURE (args->get_Uri (&navigationTargetUri));
45- std::wstring uriTarget (navigationTargetUri.get ());
46-
47- if (AreFileUrisEqual (sampleUri, uriTarget))
48- {
49- // ! [AddHostObjectToScript]
50- VARIANT remoteObjectAsVariant = {};
51- m_hostObject.query_to <IDispatch>(&remoteObjectAsVariant.pdispVal );
52- remoteObjectAsVariant.vt = VT_DISPATCH;
53-
54- // We can call AddHostObjectToScript multiple times in a row without
55- // calling RemoveHostObject first. This will replace the previous object
56- // with the new object. In our case this is the same object and everything
57- // is fine.
58- CHECK_FAILURE (
59- m_webView->AddHostObjectToScript (L" sample" , &remoteObjectAsVariant));
60- remoteObjectAsVariant.pdispVal ->Release ();
61- // ! [AddHostObjectToScript]
62- }
63- else
64- {
65- // We can call RemoveHostObject multiple times in a row without
66- // calling AddHostObjectToScript first. This will produce an error
67- // result so we ignore the failure.
68- m_webView->RemoveHostObjectFromScript (L" sample" );
69-
70- // When we navigate elsewhere we're off of the sample
71- // scenario page and so should remove the scenario.
72- m_appWindow->DeleteComponent (this );
73- }
74-
75- return S_OK;
76- }).Get (), &m_navigationStartingToken));
39+ [this , sampleUri](
40+ ICoreWebView2* sender,
41+ ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT
42+ {
43+ wil::unique_cotaskmem_string navigationTargetUri;
44+ CHECK_FAILURE (args->get_Uri (&navigationTargetUri));
45+ std::wstring uriTarget (navigationTargetUri.get ());
46+
47+ if (AreFileUrisEqual (sampleUri, uriTarget))
48+ {
49+ // ! [AddHostObjectToScript]
50+ VARIANT remoteObjectAsVariant = {};
51+ m_hostObject.query_to <IDispatch>(&remoteObjectAsVariant.pdispVal );
52+ remoteObjectAsVariant.vt = VT_DISPATCH;
53+
54+ // We can call AddHostObjectToScript multiple times in a row without
55+ // calling RemoveHostObject first. This will replace the previous object
56+ // with the new object. In our case this is the same object and everything
57+ // is fine.
58+ CHECK_FAILURE (
59+ m_webView->AddHostObjectToScript (L" sample" , &remoteObjectAsVariant));
60+ remoteObjectAsVariant.pdispVal ->Release ();
61+ // ! [AddHostObjectToScript]
62+ }
63+ else
64+ {
65+ // We can call RemoveHostObject multiple times in a row without
66+ // calling AddHostObjectToScript first. This will produce an error
67+ // result so we ignore the failure.
68+ m_webView->RemoveHostObjectFromScript (L" sample" );
69+
70+ // When we navigate elsewhere we're off of the sample
71+ // scenario page and so should remove the scenario.
72+ m_appWindow->DeleteComponent (this );
73+ }
74+
75+ return S_OK;
76+ })
77+ .Get (),
78+ &m_navigationStartingToken));
7779
7880 wil::com_ptr<ICoreWebView2_4> webview2_4 = m_webView.try_query <ICoreWebView2_4>();
7981 if (webview2_4)
@@ -83,63 +85,70 @@ ScenarioAddHostObject::ScenarioAddHostObject(AppWindow* appWindow)
8385 CHECK_FAILURE (webview2_4->add_FrameCreated (
8486 Callback<ICoreWebView2FrameCreatedEventHandler>(
8587 [this ](
86- ICoreWebView2* sender,
87- ICoreWebView2FrameCreatedEventArgs* args) -> HRESULT
88- {
89- wil::com_ptr<ICoreWebView2Frame> webviewFrame;
90- CHECK_FAILURE (args->get_Frame (&webviewFrame));
91-
92- wil::unique_cotaskmem_string name;
93- CHECK_FAILURE (webviewFrame->get_Name (&name));
94- if (std::wcscmp (name.get (), L" iframe_name" ) == 0 )
95- {
96- // ! [AddHostObjectToScriptWithOrigins]
97- wil::unique_variant remoteObjectAsVariant;
98- // It will throw if m_hostObject fails the QI, but because it is our object
99- // it should always succeed.
100- m_hostObject.query_to <IDispatch>(&remoteObjectAsVariant.pdispVal );
101- remoteObjectAsVariant.vt = VT_DISPATCH;
102-
103- // Create list of origins which will be checked.
104- // iframe will have access to host object only if its origin belongs
105- // to this list.
106- LPCWSTR origin = L" https://appassets.example/" ;
107-
108- CHECK_FAILURE (webviewFrame->AddHostObjectToScriptWithOrigins (
109- L" sample" , &remoteObjectAsVariant, 1 , &origin));
110- // ! [AddHostObjectToScriptWithOrigins]
111- }
112-
113- // Subscribe to frame name changed event
114- webviewFrame->add_NameChanged (
115- Callback<ICoreWebView2FrameNameChangedEventHandler>(
116- [this ](ICoreWebView2Frame* sender, IUnknown* args) -> HRESULT {
117- wil::unique_cotaskmem_string newName;
118- CHECK_FAILURE (sender->get_Name (&newName));
119- // Handle name changed event
120- return S_OK;
121- }).Get (), NULL );
122-
123- // Subscribe to frame destroyed event
124- webviewFrame->add_Destroyed (
125- Callback<ICoreWebView2FrameDestroyedEventHandler>(
126- [this ](ICoreWebView2Frame* sender, IUnknown* args) -> HRESULT {
127- /* Cleanup on frame destruction*/
128- return S_OK;
129- })
130- .Get (),
131- NULL );
132- return S_OK;
133- }).Get (), &m_frameCreatedToken));
88+ ICoreWebView2* sender, ICoreWebView2FrameCreatedEventArgs* args) -> HRESULT
89+ {
90+ wil::com_ptr<ICoreWebView2Frame> webviewFrame;
91+ CHECK_FAILURE (args->get_Frame (&webviewFrame));
92+
93+ wil::unique_cotaskmem_string name;
94+ CHECK_FAILURE (webviewFrame->get_Name (&name));
95+ if (std::wcscmp (name.get (), L" iframe_name" ) == 0 )
96+ {
97+ // ! [AddHostObjectToScriptWithOrigins]
98+ wil::unique_variant remoteObjectAsVariant;
99+ // It will throw if m_hostObject fails the QI, but because it is our
100+ // object it should always succeed.
101+ m_hostObject.query_to <IDispatch>(&remoteObjectAsVariant.pdispVal );
102+ remoteObjectAsVariant.vt = VT_DISPATCH;
103+
104+ // Create list of origins which will be checked.
105+ // iframe will have access to host object only if its origin belongs
106+ // to this list.
107+ LPCWSTR origin = L" https://appassets.example/" ;
108+
109+ CHECK_FAILURE (webviewFrame->AddHostObjectToScriptWithOrigins (
110+ L" sample" , &remoteObjectAsVariant, 1 , &origin));
111+ // ! [AddHostObjectToScriptWithOrigins]
112+ }
113+
114+ // Subscribe to frame name changed event
115+ webviewFrame->add_NameChanged (
116+ Callback<ICoreWebView2FrameNameChangedEventHandler>(
117+ [this ](ICoreWebView2Frame* sender, IUnknown* args) -> HRESULT
118+ {
119+ wil::unique_cotaskmem_string newName;
120+ CHECK_FAILURE (sender->get_Name (&newName));
121+ // Handle name changed event
122+ return S_OK;
123+ })
124+ .Get (),
125+ NULL );
126+
127+ // Subscribe to frame destroyed event
128+ webviewFrame->add_Destroyed (
129+ Callback<ICoreWebView2FrameDestroyedEventHandler>(
130+ [this ](ICoreWebView2Frame* sender, IUnknown* args) -> HRESULT
131+ {
132+ /* Cleanup on frame destruction*/
133+ return S_OK;
134+ })
135+ .Get (),
136+ NULL );
137+ return S_OK;
138+ })
139+ .Get (),
140+ &m_frameCreatedToken));
134141 }
135-
136142 CHECK_FAILURE (m_webView->Navigate (sampleUri.c_str ()));
137143}
138-
139144ScenarioAddHostObject::~ScenarioAddHostObject ()
140145{
141146 m_webView->RemoveHostObjectFromScript (L" sample" );
142147 m_webView->remove_NavigationStarting (m_navigationStartingToken);
148+ if (m_navigationCompletedToken.value )
149+ {
150+ m_webView->remove_NavigationCompleted (m_navigationCompletedToken);
151+ }
143152 wil::com_ptr<ICoreWebView2_4> webview2_4 = m_webView.try_query <ICoreWebView2_4>();
144153 if (webview2_4)
145154 {
0 commit comments