# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1573206556 0 # Node ID 663d79f28e463602294a03c18aaf039a1bf34dc6 # Parent 686b2d049056095453e4a903c353cd5d76ea86dd 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. diff -r 686b2d049056 -r 663d79f28e46 win/browser.c --- 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 #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. diff -r 686b2d049056 -r 663d79f28e46 win/dw.c --- 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 diff -r 686b2d049056 -r 663d79f28e46 win/edge.cpp --- 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( [hwnd, scriptdata](HRESULT error, PCWSTR result) -> HRESULT {