comparison win/edge.cpp @ 2041:638be5b17715

Win: Only create one environment during dw_edge_detect() ... if it fails there is no Edge. Previously we created an environment for each edge HTML widget, and one during detection.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 24 Nov 2019 06:59:52 +0000
parents 89d62197124b
children 0d8b898b03e2
comparison
equal deleted inserted replaced
2040:2c56a8e245e8 2041:638be5b17715
14 #include <wrl.h> 14 #include <wrl.h>
15 15
16 using namespace Microsoft::WRL; 16 using namespace Microsoft::WRL;
17 17
18 #define _DW_HTML_DATA_NAME "_dw_edge" 18 #define _DW_HTML_DATA_NAME "_dw_edge"
19 #define _DW_HTML_DATA_ENV "_dw_edge_env"
20 #define _DW_HTML_DATA_LOCATION "_dw_edge_location" 19 #define _DW_HTML_DATA_LOCATION "_dw_edge_location"
21 #define _DW_HTML_DATA_RAW "_dw_edge_raw" 20 #define _DW_HTML_DATA_RAW "_dw_edge_raw"
22 21
23 extern "C" { 22 extern "C" {
24 23
27 char *_myWideToUTF8(LPCWSTR widestring, void *outbuf); 26 char *_myWideToUTF8(LPCWSTR widestring, void *outbuf);
28 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL) 27 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL)
29 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL) 28 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL)
30 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2); 29 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
31 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam); 30 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam);
32 extern HWND DW_HWND_OBJECT; 31 IWebView2Environment *DW_EDGE_ENV = NULL;
33 BOOL DW_EDGE_DETECTED = FALSE;
34 32
35 /******************************* dw_edge_detect() ************************** 33 /******************************* dw_edge_detect() **************************
36 * Attempts to create a temporary Edge (Chromium) browser context... 34 * Attempts to create a temporary Edge (Chromium) browser context...
37 * If we succeed return TRUE and use Edge for HTML windows. 35 * If we succeed return TRUE and use Edge for HTML windows.
38 * If it fails return FALSE and fall back to using embedded IE. 36 * If it fails return FALSE and fall back to using embedded IE.
39 */ 37 */
40 BOOL _dw_edge_detect(VOID) 38 BOOL _dw_edge_detect(VOID)
41 { 39 {
42 HWND hWnd = DW_HWND_OBJECT;
43
44 CreateWebView2EnvironmentWithDetails(nullptr, nullptr, nullptr, 40 CreateWebView2EnvironmentWithDetails(nullptr, nullptr, nullptr,
45 Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>( 41 Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>(
46 [hWnd](HRESULT result, IWebView2Environment* env) -> HRESULT { 42 [](HRESULT result, IWebView2Environment* env) -> HRESULT {
47 // Successfully created Edge environment, return TRUE 43 // Successfully created Edge environment, return TRUE
48 DW_EDGE_DETECTED = TRUE; 44 DW_EDGE_ENV = env;
49 return S_OK; 45 return S_OK;
50 }).Get()); 46 }).Get());
51 return DW_EDGE_DETECTED; 47 return DW_EDGE_ENV ? TRUE : FALSE;
52 } 48 }
53 49
54 /******************************* dw_edge_action() ************************** 50 /******************************* dw_edge_action() **************************
55 * Implements the functionality of a "Back". "Forward", "Home", "Search", 51 * Implements the functionality of a "Back". "Forward", "Home", "Search",
56 * "Refresh", or "Stop" button. 52 * "Refresh", or "Stop" button.
240 } 236 }
241 237
242 case WM_CREATE: 238 case WM_CREATE:
243 { 239 {
244 // Step 3 - Create a single WebView within the parent window 240 // Step 3 - Create a single WebView within the parent window
245 // Locate the browser and set up the environment for WebView 241 // Create a WebView, whose parent is the main window hWnd
246 CreateWebView2EnvironmentWithDetails(nullptr, nullptr, nullptr, 242 DW_EDGE_ENV->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
247 Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>( 243 [hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT {
248 [hWnd](HRESULT result, IWebView2Environment* env) -> HRESULT { 244 if (webview != nullptr) {
249 245 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(webview));
250 // Save the environment for later use 246 }
251 dw_window_set_data(hWnd, _DW_HTML_DATA_ENV, DW_POINTER(env)); 247
252 248 // Add a few settings for the webview
253 // Create a WebView, whose parent is the main window hWnd 249 // this is a redundant demo step as they are the default settings values
254 env->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>( 250 IWebView2Settings* Settings;
255 [hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT { 251 webview->get_Settings(&Settings);
256 if (webview != nullptr) { 252 Settings->put_IsScriptEnabled(TRUE);
257 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(webview)); 253 Settings->put_AreDefaultScriptDialogsEnabled(TRUE);
258 } 254 Settings->put_IsWebMessageEnabled(TRUE);
259 255
260 // Add a few settings for the webview 256 // Resize WebView to fit the bounds of the parent window
261 // this is a redundant demo step as they are the default settings values 257 RECT bounds;
262 IWebView2Settings* Settings; 258 GetClientRect(hWnd, &bounds);
263 webview->get_Settings(&Settings); 259 webview->put_Bounds(bounds);
264 Settings->put_IsScriptEnabled(TRUE); 260
265 Settings->put_AreDefaultScriptDialogsEnabled(TRUE); 261 // Save the token, we might need to dw_window_set_data() this value
266 Settings->put_IsWebMessageEnabled(TRUE); 262 // for later use to remove the handlers
267 263 EventRegistrationToken token;
268 // Resize WebView to fit the bounds of the parent window 264
269 RECT bounds; 265 // Register a handler for the NavigationStarting event.
270 GetClientRect(hWnd, &bounds); 266 webview->add_NavigationStarting(
271 webview->put_Bounds(bounds); 267 Callback<IWebView2NavigationStartingEventHandler>(
272 268 [hWnd](IWebView2WebView* sender,
273 // Save the token, we might need to dw_window_set_data() this value 269 IWebView2NavigationStartingEventArgs* args) -> HRESULT
274 // for later use to remove the handlers 270 {
275 EventRegistrationToken token; 271 LPWSTR uri;
276 272 sender->get_Source(&uri);
277 // Register a handler for the NavigationStarting event. 273
278 webview->add_NavigationStarting( 274 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED),
279 Callback<IWebView2NavigationStartingEventHandler>( 275 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
280 [hWnd](IWebView2WebView* sender, 276
281 IWebView2NavigationStartingEventArgs* args) -> HRESULT
282 {
283 LPWSTR uri;
284 sender->get_Source(&uri);
285
286 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED),
287 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
288
289 return S_OK;
290 }).Get(), &token);
291
292 // Register a handler for the DocumentStateChanged event.
293 webview->add_DocumentStateChanged(
294 Callback<IWebView2DocumentStateChangedEventHandler>(
295 [hWnd](IWebView2WebView* sender,
296 IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
297 {
298 LPWSTR uri;
299 sender->get_Source(&uri);
300
301 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING),
302 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
303
304 return S_OK;
305 }).Get(), &token);
306
307 // Register a handler for the NavigationCompleted event.
308 webview->add_NavigationCompleted(
309 Callback<IWebView2NavigationCompletedEventHandler>(
310 [hWnd](IWebView2WebView* sender,
311 IWebView2NavigationCompletedEventArgs* args) -> HRESULT
312 {
313 LPWSTR uri;
314 sender->get_Source(&uri);
315
316 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE),
317 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
318
319 return S_OK;
320 }).Get(), &token);
321
322 // Handle cached load requests due to delayed
323 // loading of the edge webview contexts
324 LPCWSTR url = (LPCWSTR)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION);
325 if(url)
326 {
327 webview->Navigate(url);
328 free((void *)url);
329 }
330 LPCWSTR raw = (LPCWSTR)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW);
331 if (raw)
332 {
333 webview->NavigateToString(raw);
334 free((void *)raw);
335 }
336 return S_OK; 277 return S_OK;
337 }).Get()); 278 }).Get(), &token);
338 return S_OK; 279
339 }).Get()); 280 // Register a handler for the DocumentStateChanged event.
340 281 webview->add_DocumentStateChanged(
282 Callback<IWebView2DocumentStateChangedEventHandler>(
283 [hWnd](IWebView2WebView* sender,
284 IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
285 {
286 LPWSTR uri;
287 sender->get_Source(&uri);
288
289 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING),
290 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
291
292 return S_OK;
293 }).Get(), &token);
294
295 // Register a handler for the NavigationCompleted event.
296 webview->add_NavigationCompleted(
297 Callback<IWebView2NavigationCompletedEventHandler>(
298 [hWnd](IWebView2WebView* sender,
299 IWebView2NavigationCompletedEventArgs* args) -> HRESULT
300 {
301 LPWSTR uri;
302 sender->get_Source(&uri);
303
304 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE),
305 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
306
307 return S_OK;
308 }).Get(), &token);
309
310 // Handle cached load requests due to delayed
311 // loading of the edge webview contexts
312 LPCWSTR url = (LPCWSTR)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION);
313 if(url)
314 {
315 webview->Navigate(url);
316 free((void *)url);
317 }
318 LPCWSTR raw = (LPCWSTR)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW);
319 if (raw)
320 {
321 webview->NavigateToString(raw);
322 free((void *)raw);
323 }
324 return S_OK;
325 }).Get());
341 // Success 326 // Success
342 return(0); 327 return(0);
343 } 328 }
344 329
345 case WM_DESTROY: 330 case WM_DESTROY: