comparison win/browser.c @ 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
comparison
equal deleted inserted replaced
2017:686b2d049056 2018:663d79f28e46
27 #include <mshtml.h> // Defines of stuff like IHTMLDocument2. This is an include file with Visual C 6 and above 27 #include <mshtml.h> // Defines of stuff like IHTMLDocument2. This is an include file with Visual C 6 and above
28 #include <mshtmhst.h> // Defines of stuff like IDocHostUIHandler. This is an include file with Visual C 6 and above 28 #include <mshtmhst.h> // Defines of stuff like IDocHostUIHandler. This is an include file with Visual C 6 and above
29 #include <crtdbg.h> // for _ASSERT() 29 #include <crtdbg.h> // for _ASSERT()
30 #include <initguid.h> 30 #include <initguid.h>
31 #include "dw.h" 31 #include "dw.h"
32
33 /* Import the character conversion functions from dw.c */
34 LPWSTR _myUTF8toWide(char *utf8string, void *outbuf);
35 char *_myWideToUTF8(LPWSTR widestring, void *outbuf);
36 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL)
37 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL)
38 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
32 39
33 // This is used by DisplayHTMLStr(). It can be global because we never change it. 40 // This is used by DisplayHTMLStr(). It can be global because we never change it.
34 static const SAFEARRAYBOUND ArrayBound = {1, 0}; 41 static const SAFEARRAYBOUND ArrayBound = {1, 0};
35 42
36 // Our IStorage functions that the browser may call 43 // Our IStorage functions that the browser may call
1077 1084
1078 1085
1079 // The DWEventHandler object must be created by an application using IWebBRowser2, 1086 // The DWEventHandler object must be created by an application using IWebBRowser2,
1080 // and given to IWebBrowser2's IConnectPoint object (via 1087 // and given to IWebBrowser2's IConnectPoint object (via
1081 // IConnectPoint's Advise function). 1088 // IConnectPoint's Advise function).
1082 // {4115B8E2-1823-4bbc-B10D-3D33AAA12ACF}
1083 1089
1084 // DWEventHandler VTable's GUID 1090 // DWEventHandler VTable's GUID
1085 // {d2d531c4-83d7-48d7-b733-840245ea2b34} 1091 // {d2d531c4-83d7-48d7-b733-840245ea2b34}
1086 DEFINE_GUID(DIID_DWEventHandler, 0xd2d531c4, 0x83d7, 0x48d7, 0xb7, 0x33, 0x84, 0x2, 0x45, 0xea, 0x2b, 0x34); 1092 DEFINE_GUID(DIID_DWEventHandler, 0xd2d531c4, 0x83d7, 0x48d7, 0xb7, 0x33, 0x84, 0x2, 0x45, 0xea, 0x2b, 0x34);
1087 1093
1135 1141
1136 // This is the extra function for DWEventHandler. 1142 // This is the extra function for DWEventHandler.
1137 1143
1138 static void STDMETHODCALLTYPE DWEventHandler_DocumentComplete(DWEventHandler *this, IDispatch* pDisp, VARIANT* URL) 1144 static void STDMETHODCALLTYPE DWEventHandler_DocumentComplete(DWEventHandler *this, IDispatch* pDisp, VARIANT* URL)
1139 { 1145 {
1140 // Do a compare of the two elements. We happen to know that
1141 // we'll be passing an array of DWORD values to Sort()
1142 dw_debug("DocumentComplete() called!\n"); 1146 dw_debug("DocumentComplete() called!\n");
1143 } 1147 }
1144 1148
1145 1149
1146 // Our DWEventHandler VTable. We need only one of these, so we can 1150 // Our DWEventHandler VTable. We need only one of these, so we can
1455 // nul-terminated C strings. So, by using a VARIENT, whose first field tells what sort of 1459 // nul-terminated C strings. So, by using a VARIENT, whose first field tells what sort of
1456 // data (ie, string, float, etc) is in the VARIENT, COM interfaces can be used by just about 1460 // data (ie, string, float, etc) is in the VARIENT, COM interfaces can be used by just about
1457 // any language. 1461 // any language.
1458 VariantInit(&myURL); 1462 VariantInit(&myURL);
1459 myURL.vt = VT_BSTR; 1463 myURL.vt = VT_BSTR;
1460 1464 myURL.bstrVal = SysAllocString(UTF8toWide(url));
1461 {
1462 wchar_t *buffer;
1463 DWORD size;
1464
1465 size = MultiByteToWideChar(CP_ACP, 0, url, -1, 0, 0);
1466 if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto badalloc;
1467 MultiByteToWideChar(CP_ACP, 0, url, -1, buffer, size);
1468 myURL.bstrVal = SysAllocString(buffer);
1469 GlobalFree(buffer);
1470 }
1471 if (!myURL.bstrVal) 1465 if (!myURL.bstrVal)
1472 { 1466 {
1473 badalloc: webBrowser2->lpVtbl->Release(webBrowser2); 1467 webBrowser2->lpVtbl->Release(webBrowser2);
1474 return(-6); 1468 return(-6);
1475 } 1469 }
1476 1470
1477 // Call the Navigate2() function to actually display the page. 1471 // Call the Navigate2() function to actually display the page.
1478 webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0); 1472 webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0);
1501 * scriptdata = Pointer to user data to be passed to the callback. 1495 * scriptdata = Pointer to user data to be passed to the callback.
1502 * 1496 *
1503 * RETURNS: 0 if success, or non-zero if an error. 1497 * RETURNS: 0 if success, or non-zero if an error.
1504 */ 1498 */
1505 1499
1506 int _dw_html_javascript_run(HWND hwnd, LPCWSTR script, void *scriptdata) 1500 int _dw_html_javascript_run(HWND hwnd, char *script, void *scriptdata)
1507 { 1501 {
1502 IWebBrowser2 *webBrowser2;
1508 IHTMLWindow2 *htmlWindow2; 1503 IHTMLWindow2 *htmlWindow2;
1504 IHTMLDocument2 *htmlDocument2;
1509 IOleObject *browserObject; 1505 IOleObject *browserObject;
1510 VARIANT retVal; 1506 VARIANT result;
1507 int retval = DW_ERROR_UNKNOWN;
1511 1508
1512 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when 1509 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
1513 // we initially attached the browser object to this window. 1510 // we initially attached the browser object to this window.
1514 browserObject = *((IOleObject **)dw_window_get_data(hwnd, "_dw_html")); 1511 browserObject = *((IOleObject **)dw_window_get_data(hwnd, "_dw_html"));
1515 1512
1516 // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser 1513 // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
1517 // object, so we can call some of the functions in the former's table. 1514 // object, so we can call some of the functions in the former's table.
1518 if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IHTMLWindow2, (void**)&htmlWindow2)) 1515 if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
1519 { 1516 {
1520 BSTR myscript = SysAllocString(script); 1517 IDispatch *pDp;
1521 if (myscript) 1518
1519 if(!webBrowser2->lpVtbl->get_Document(webBrowser2, &pDp))
1522 { 1520 {
1523 htmlWindow2->lpVtbl->execScript(htmlWindow2, myscript, NULL, &retVal); 1521 if (!pDp->lpVtbl->QueryInterface(pDp, &IID_IHTMLDocument2, (void**)&htmlDocument2))
1524 SysFreeString(myscript); 1522 {
1523 if (!htmlDocument2->lpVtbl->get_parentWindow(htmlDocument2, &htmlWindow2))
1524 {
1525 BSTR myscript = SysAllocString(UTF8toWide(script));
1526 if (myscript)
1527 {
1528 HRESULT hr;
1529
1530 VariantInit(&result);
1531 hr = htmlWindow2->lpVtbl->execScript(htmlWindow2, myscript, L"javascript", &result);
1532 /* Pass the result back for event handling */
1533 _wndproc(hwnd, WM_USER+100, (WPARAM)(result.vt == VT_BSTR ? WideToUTF8(result.bstrVal) : NULL), (LPARAM)scriptdata);
1534 VariantClear(&result);
1535 SysFreeString(myscript);
1536 retval = DW_ERROR_NONE;
1537 }
1538 // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it,
1539 // so we can release our hold on it). Note that we'll still maintain our hold on the browser
1540 // object.
1541 htmlWindow2->lpVtbl->Release(htmlWindow2);
1542 }
1543 htmlDocument2->lpVtbl->Release(htmlDocument2);
1544 }
1545 pDp->lpVtbl->Release(pDp);
1525 } 1546 }
1526 // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it, 1547 webBrowser2->lpVtbl->Release(webBrowser2);
1527 // so we can release our hold on it). Note that we'll still maintain our hold on the browser
1528 // object.
1529 htmlWindow2->lpVtbl->Release(htmlWindow2);
1530 } 1548 }
1531 return DW_ERROR_UNKNOWN; 1549 return retval;
1532 } 1550 }
1551
1533 1552
1534 1553
1535 /******************************* ResizeBrowser() **************************** 1554 /******************************* ResizeBrowser() ****************************
1536 * Resizes the browser object for the specified window to the specified 1555 * Resizes the browser object for the specified window to the specified
1537 * width and height. 1556 * width and height.