changeset 2043:82e5c998df2e

Win: Fix crash on Edge HTML widget destruction. Skip freeing memory from chromium widget windows.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 24 Nov 2019 22:42:55 +0000
parents 0d8b898b03e2
children b74b9afa31aa
files win/dw.c win/edge.cpp
diffstat 2 files changed, 112 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/win/dw.c	Sun Nov 24 21:01:46 2019 +0000
+++ b/win/dw.c	Sun Nov 24 22:42:55 2019 +0000
@@ -961,8 +961,9 @@
       
    GetClassName(handle, tmpbuf, 99);
 
-   /* Don't try to free memory from an OLE embedded IE */
-   if(_tcsncmp(tmpbuf, TEXT("Internet Explorer_Server"), 25) == 0)
+   /* Don't try to free memory from an embedded IE or Edge/Chromium window */
+   if(_tcsncmp(tmpbuf, TEXT("Internet Explorer_Server"), 25) == 0 ||
+	   _tcsncmp(tmpbuf, TEXT("Chrome_WidgetWin_"), 17) == 0)
       return TRUE;
 
    /* Delete font, icon and bitmap GDI objects in use */
--- a/win/edge.cpp	Sun Nov 24 21:01:46 2019 +0000
+++ b/win/edge.cpp	Sun Nov 24 22:42:55 2019 +0000
@@ -27,7 +27,6 @@
 	#define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL)
 	#define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL)
 	LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
-	BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam);
 }
 
 class EdgeBrowser
@@ -58,136 +57,135 @@
 {
 	switch (uMsg)
 	{
-	case WM_SIZE:
-	{
-		// Resize the browser object to fit the window
-		EdgeWebView *webview;
+		case WM_SIZE:
+		{
+			// Resize the browser object to fit the window
+			EdgeWebView *webview;
 
-		// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
-		// we initially attached the browser object to this window.
-		webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME);
-		// Resize WebView to fit the bounds of the parent window
-		if (webview)
-			webview->DoSize();
-		return(0);
-	}
+			// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
+			// we initially attached the browser object to this window.
+			webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME);
+			// Resize WebView to fit the bounds of the parent window
+			if (webview)
+				webview->DoSize();
+			return(0);
+		}
 
-	case WM_PAINT:
-	{
-		PAINTSTRUCT ps;
-		HDC hdc = BeginPaint(hWnd, &ps);
-		EndPaint(hWnd, &ps);
-		return(0);
-	}
+		case WM_PAINT:
+		{
+			PAINTSTRUCT ps;
+			HDC hdc = BeginPaint(hWnd, &ps);
+			EndPaint(hWnd, &ps);
+			return(0);
+		}
 
-	case WM_CREATE:
-	{
-		// Step 3 - Create a single WebView within the parent window
-		// Create a WebView, whose parent is the main window hWnd
-		Env->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
-			[hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT {
-				EdgeWebView* WebView = new EdgeWebView;
+		case WM_CREATE:
+		{
+			// Step 3 - Create a single WebView within the parent window
+			// Create a WebView, whose parent is the main window hWnd
+			Env->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
+				[hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT {
+					EdgeWebView* WebView = new EdgeWebView;
 
-				WebView->Setup(hWnd, webview);
-				dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(WebView));
+					WebView->Setup(hWnd, webview);
+					dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(WebView));
 
-				// Add a few settings for the webview
-				// this is a redundant demo step as they are the default settings values
-				IWebView2Settings* Settings;
-				webview->get_Settings(&Settings);
-				Settings->put_IsScriptEnabled(TRUE);
-				Settings->put_AreDefaultScriptDialogsEnabled(TRUE);
-				Settings->put_IsWebMessageEnabled(TRUE);
+					// Add a few settings for the webview
+					// this is a redundant demo step as they are the default settings values
+					IWebView2Settings* Settings;
+					webview->get_Settings(&Settings);
+					Settings->put_IsScriptEnabled(TRUE);
+					Settings->put_AreDefaultScriptDialogsEnabled(TRUE);
+					Settings->put_IsWebMessageEnabled(TRUE);
 
-				// Resize WebView to fit the bounds of the parent window
-				WebView->DoSize();
+					// Resize WebView to fit the bounds of the parent window
+					WebView->DoSize();
 
-				// Save the token, we might need to dw_window_set_data() this value
-				// for later use to remove the handlers
-				EventRegistrationToken token;
+					// Save the token, we might need to dw_window_set_data() this value
+					// for later use to remove the handlers
+					EventRegistrationToken token;
 
-				// Register a handler for the NavigationStarting event.
-				webview->add_NavigationStarting(
-					Callback<IWebView2NavigationStartingEventHandler>(
-						[hWnd](IWebView2WebView* sender,
-							IWebView2NavigationStartingEventArgs* args) -> HRESULT
-						{
-							LPWSTR uri;
-							sender->get_Source(&uri);
+					// Register a handler for the NavigationStarting event.
+					webview->add_NavigationStarting(
+						Callback<IWebView2NavigationStartingEventHandler>(
+							[hWnd](IWebView2WebView* sender,
+								IWebView2NavigationStartingEventArgs* args) -> HRESULT
+							{
+								LPWSTR uri;
+								sender->get_Source(&uri);
 
-							_wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED),
-								!wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
+								_wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED),
+									!wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
 
-							return S_OK;
-						}).Get(), &token);
+								return S_OK;
+							}).Get(), &token);
 
-				// Register a handler for the DocumentStateChanged event.
-				webview->add_DocumentStateChanged(
-					Callback<IWebView2DocumentStateChangedEventHandler>(
-						[hWnd](IWebView2WebView* sender,
-							IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
-						{
-							LPWSTR uri;
-							sender->get_Source(&uri);
+					// Register a handler for the DocumentStateChanged event.
+					webview->add_DocumentStateChanged(
+						Callback<IWebView2DocumentStateChangedEventHandler>(
+							[hWnd](IWebView2WebView* sender,
+								IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
+							{
+								LPWSTR uri;
+								sender->get_Source(&uri);
 
-							_wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING),
-								!wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
+								_wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING),
+									!wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
 
-							return S_OK;
-						}).Get(), &token);
+								return S_OK;
+							}).Get(), &token);
 
-				// Register a handler for the NavigationCompleted event.
-				webview->add_NavigationCompleted(
-					Callback<IWebView2NavigationCompletedEventHandler>(
-						[hWnd](IWebView2WebView* sender,
-							IWebView2NavigationCompletedEventArgs* args) -> HRESULT
-						{
-							LPWSTR uri;
-							sender->get_Source(&uri);
+					// Register a handler for the NavigationCompleted event.
+					webview->add_NavigationCompleted(
+						Callback<IWebView2NavigationCompletedEventHandler>(
+							[hWnd](IWebView2WebView* sender,
+								IWebView2NavigationCompletedEventArgs* args) -> HRESULT
+							{
+								LPWSTR uri;
+								sender->get_Source(&uri);
 
-							_wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE),
-								!wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
+								_wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE),
+									!wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
 
-							return S_OK;
-						}).Get(), &token);
+								return S_OK;
+							}).Get(), &token);
 
-				// Handle cached load requests due to delayed
-				// loading of the edge webview contexts
-				char *url = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION);
-				if (url)
-				{
-					WebView->URL(url);
-					free((void*)url);
-				}
-				char *raw = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW);
-				if (raw)
-				{
-					WebView->Raw(raw);
-					free((void*)raw);
-				}
-				return S_OK;
-			}).Get());
-		// Success
-		return(0);
-	}
+					// Handle cached load requests due to delayed
+					// loading of the edge webview contexts
+					char *url = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION);
+					if (url)
+					{
+						WebView->URL(url);
+						free((void*)url);
+					}
+					char *raw = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW);
+					if (raw)
+					{
+						WebView->Raw(raw);
+						free((void*)raw);
+					}
+					return S_OK;
+				}).Get());
+			// Success
+			return(0);
+		}
 
-	case WM_DESTROY:
-	{
-		// Detach the browser object from this window, and free resources.
-		EdgeWebView *webview;
+		case WM_DESTROY:
+		{
+			// Detach the browser object from this window, and free resources.
+			EdgeWebView *webview;
 
-		// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
-		// we initially attached the browser object to this window.
-		webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME);
-		if (webview)
-		{
-			dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, NULL);
-			webview->Close();
-			delete webview;
+			// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
+			// we initially attached the browser object to this window.
+			webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME);
+			if (webview)
+			{
+				dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, NULL);
+				webview->Close();
+				delete webview;
+			}
+			return(TRUE);
 		}
-		_free_window_memory(hWnd, 0);
-		return(TRUE);
-	}
 	}
 
 	return(DefWindowProc(hWnd, uMsg, wParam, lParam));