changeset 2018:663d79f28e46

Win: Fix dw_html_javascript_run() when using embedded IE browser widget. Switched both the Edge and IE modules to use the main UTF8 conversion utils.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 08 Nov 2019 09:49:16 +0000
parents 686b2d049056
children 583c2d62845c
files win/browser.c win/dw.c win/edge.cpp
diffstat 3 files changed, 66 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/win/browser.c	Fri Nov 08 07:20:17 2019 +0000
+++ b/win/browser.c	Fri Nov 08 09:49:16 2019 +0000
@@ -30,6 +30,13 @@
 #include <initguid.h>
 #include "dw.h"
 
+/* Import the character conversion functions from dw.c */
+LPWSTR _myUTF8toWide(char *utf8string, void *outbuf);
+char *_myWideToUTF8(LPWSTR widestring, void *outbuf);
+#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);
+
 // This is used by DisplayHTMLStr(). It can be global because we never change it.
 static const SAFEARRAYBOUND ArrayBound = {1, 0};
 
@@ -1079,7 +1086,6 @@
 // The DWEventHandler object must be created by an application using IWebBRowser2,
 // and given to IWebBrowser2's IConnectPoint object (via
 // IConnectPoint's Advise function).
-// {4115B8E2-1823-4bbc-B10D-3D33AAA12ACF}
 
 // DWEventHandler VTable's GUID
 // {d2d531c4-83d7-48d7-b733-840245ea2b34}
@@ -1137,8 +1143,6 @@
 
 static void STDMETHODCALLTYPE DWEventHandler_DocumentComplete(DWEventHandler *this, IDispatch* pDisp, VARIANT* URL)
 {
-	// Do a compare of the two elements. We happen to know that
-	// we'll be passing an array of DWORD values to Sort()
 	dw_debug("DocumentComplete() called!\n");
 }
 
@@ -1457,20 +1461,10 @@
 		// any language.
 		VariantInit(&myURL);
 		myURL.vt = VT_BSTR;
-
-		{
-			wchar_t		*buffer;
-			DWORD		size;
-
-			size = MultiByteToWideChar(CP_ACP, 0, url, -1, 0, 0);
-			if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto badalloc;
-			MultiByteToWideChar(CP_ACP, 0, url, -1, buffer, size);
-			myURL.bstrVal = SysAllocString(buffer);
-			GlobalFree(buffer);
-		}
+		myURL.bstrVal = SysAllocString(UTF8toWide(url));
 		if (!myURL.bstrVal)
 		{
-badalloc:	webBrowser2->lpVtbl->Release(webBrowser2);
+			webBrowser2->lpVtbl->Release(webBrowser2);
 			return(-6);
 		}
 
@@ -1503,11 +1497,14 @@
  * RETURNS: 0 if success, or non-zero if an error.
  */
 
-int _dw_html_javascript_run(HWND hwnd, LPCWSTR script, void *scriptdata)
+int _dw_html_javascript_run(HWND hwnd, char *script, void *scriptdata)
 {
+	IWebBrowser2	*webBrowser2;
 	IHTMLWindow2	*htmlWindow2;
+	IHTMLDocument2	*htmlDocument2;
 	IOleObject		*browserObject;
-	VARIANT			retVal;
+	VARIANT			result;
+	int				retval = DW_ERROR_UNKNOWN;
 
 	// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
 	// we initially attached the browser object to this window.
@@ -1515,23 +1512,45 @@
 
 	// We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
 	// object, so we can call some of the functions in the former's table.
-	if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IHTMLWindow2, (void**)&htmlWindow2))
+	if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
 	{
-		BSTR myscript = SysAllocString(script);
-		if (myscript)
+		IDispatch *pDp;
+		
+		if(!webBrowser2->lpVtbl->get_Document(webBrowser2, &pDp))
 		{
-			htmlWindow2->lpVtbl->execScript(htmlWindow2, myscript, NULL, &retVal);
-			SysFreeString(myscript);
+			if (!pDp->lpVtbl->QueryInterface(pDp, &IID_IHTMLDocument2, (void**)&htmlDocument2))
+			{
+				if (!htmlDocument2->lpVtbl->get_parentWindow(htmlDocument2, &htmlWindow2))
+				{
+					BSTR myscript = SysAllocString(UTF8toWide(script));
+					if (myscript)
+					{
+						HRESULT hr;
+						
+						VariantInit(&result);
+						hr = htmlWindow2->lpVtbl->execScript(htmlWindow2, myscript, L"javascript", &result);
+						/* Pass the result back for event handling */
+						_wndproc(hwnd, WM_USER+100, (WPARAM)(result.vt == VT_BSTR ? WideToUTF8(result.bstrVal) : NULL), (LPARAM)scriptdata);
+						VariantClear(&result);
+						SysFreeString(myscript);
+						retval = DW_ERROR_NONE;
+					}
+					// We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it,
+					// so we can release our hold on it). Note that we'll still maintain our hold on the browser
+					// object.
+					htmlWindow2->lpVtbl->Release(htmlWindow2);
+				}
+				htmlDocument2->lpVtbl->Release(htmlDocument2);
+			}
+			pDp->lpVtbl->Release(pDp);
 		}
-		// We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it,
-		// so we can release our hold on it). Note that we'll still maintain our hold on the browser
-		// object.
-		htmlWindow2->lpVtbl->Release(htmlWindow2);
+		webBrowser2->lpVtbl->Release(webBrowser2);
 	}
-	return DW_ERROR_UNKNOWN;
+	return retval;
 }
 
 
+
 /******************************* ResizeBrowser() ****************************
  * Resizes the browser object for the specified window to the specified
  * width and height.
--- a/win/dw.c	Fri Nov 08 07:20:17 2019 +0000
+++ b/win/dw.c	Fri Nov 08 09:49:16 2019 +0000
@@ -5717,9 +5717,9 @@
 int _dw_html_javascript_run(HWND hwnd, char *script, void *scriptdata);
 #ifdef BUILD_EDGE
 void _dw_edge_action(HWND hwnd, int action);
-int _dw_edge_raw(HWND hwnd, LPCWSTR string);
-int _dw_edge_url(HWND hwnd, LPCWSTR url);
-int _dw_edge_javascript_run(HWND hwnd, LPCWSTR script, void *scriptdata);
+int _dw_edge_raw(HWND hwnd, char *string);
+int _dw_edge_url(HWND hwnd, char *url);
+int _dw_edge_javascript_run(HWND hwnd, char *script, void *scriptdata);
 #endif
 #endif
 
@@ -5755,7 +5755,7 @@
 #if (defined(BUILD_DLL) || defined(BUILD_HTML))
 #ifdef BUILD_EDGE
    if (_DW_EDGE_DETECTED)
-      return _dw_edge_raw(handle, UTF8toWide(string));
+      return _dw_edge_raw(handle, string);
 #endif
    return _dw_html_raw(handle, string);
 #else
@@ -5777,7 +5777,7 @@
 #if (defined(BUILD_DLL) || defined(BUILD_HTML))
 #if BUILD_EDGE
    if (_DW_EDGE_DETECTED)
-      return _dw_edge_url(handle, UTF8toWide(url));
+      return _dw_edge_url(handle, url);
 #endif
    return _dw_html_url(handle, url);
 #else
@@ -5800,7 +5800,7 @@
 #if (defined(BUILD_DLL) || defined(BUILD_HTML))
 #if BUILD_EDGE
    if (_DW_EDGE_DETECTED)
-      return _dw_edge_javascript_run(handle, UTF8toWide(script), scriptdata);
+      return _dw_edge_javascript_run(handle, script, scriptdata);
 #endif
    return _dw_html_javascript_run(handle, script, scriptdata);
 #else
--- a/win/edge.cpp	Fri Nov 08 07:20:17 2019 +0000
+++ b/win/edge.cpp	Fri Nov 08 09:49:16 2019 +0000
@@ -21,6 +21,12 @@
 
 extern "C" {
 
+	/* Import the character conversion functions from dw.c */
+	LPWSTR _myUTF8toWide(char *utf8string, void *outbuf);
+	char *_myWideToUTF8(LPWSTR widestring, void *outbuf);
+	#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);
 	extern HWND DW_HWND_OBJECT;
 	BOOL DW_EDGE_DETECTED = FALSE;
 
@@ -128,7 +134,7 @@
 	 * RETURNS: 0 if success, or non-zero if an error.
 	 */
 
-	int _dw_edge_raw(HWND hwnd, LPCWSTR string)
+	int _dw_edge_raw(HWND hwnd, char *string)
 	{
 		IWebView2WebView* webview;
 
@@ -137,9 +143,9 @@
 		webview = (IWebView2WebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME);
 
 		if (webview)
-			webview->NavigateToString(string);
+			webview->NavigateToString(UTF8toWide(string));
 		else
-			dw_window_set_data(hwnd, _DW_HTML_DATA_RAW, _wcsdup(string));
+			dw_window_set_data(hwnd, _DW_HTML_DATA_RAW, _wcsdup(UTF8toWide(string)));
 		return DW_ERROR_NONE;
 	}
 
@@ -152,7 +158,7 @@
 	 * RETURNS: 0 if success, or non-zero if an error.
 	 */
 
-	int _dw_edge_url(HWND hwnd, LPCWSTR url)
+	int _dw_edge_url(HWND hwnd, char *url)
 	{
 		IWebView2WebView* webview;
 
@@ -161,17 +167,12 @@
 		webview = (IWebView2WebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME);
 
 		if (webview)
-			webview->Navigate(url);
+			webview->Navigate(UTF8toWide(url));
 		else
-			dw_window_set_data(hwnd, _DW_HTML_DATA_LOCATION, _wcsdup(url));
+			dw_window_set_data(hwnd, _DW_HTML_DATA_LOCATION, _wcsdup(UTF8toWide(url)));
 		return DW_ERROR_NONE;
 	}
 
-	/* These reference functions in dw.c */
-	#define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL)
-	char* _myWideToUTF8(LPWSTR widestring, void* outbuf);
-	LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
-
 	/******************************* dw_edge_javascript_run() ****************************
 	 * Runs a javascript in the specified browser context.
 	 *
@@ -182,7 +183,7 @@
 	 * RETURNS: 0 if success, or non-zero if an error.
 	 */
 
-	int _dw_edge_javascript_run(HWND hwnd, LPCWSTR script, void *scriptdata)
+	int _dw_edge_javascript_run(HWND hwnd, char *script, void *scriptdata)
 	{
 		IWebView2WebView* webview;
 
@@ -191,7 +192,7 @@
 		webview = (IWebView2WebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME);
 
 		if (webview)
-			webview->ExecuteScript(script,
+			webview->ExecuteScript(UTF8toWide(script),
 				Callback<IWebView2ExecuteScriptCompletedHandler>(
 					[hwnd, scriptdata](HRESULT error, PCWSTR result) -> HRESULT
 					{